mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 20:40:12 +08:00
feat(multitenancy): add tenant_id as a field for data pipeline and support individual database for clickhouse (#4867)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Arun Raj M <jarnura47@gmail.com> Co-authored-by: Sampras Lopes <sampras.lopes@juspay.in>
This commit is contained in:
@ -129,6 +129,7 @@ pub struct Settings<S: SecretState> {
|
||||
pub struct Multitenancy {
|
||||
pub tenants: TenantConfig,
|
||||
pub enabled: bool,
|
||||
pub global_tenant: GlobalTenant,
|
||||
}
|
||||
|
||||
impl Multitenancy {
|
||||
@ -153,6 +154,7 @@ pub struct Tenant {
|
||||
pub base_url: String,
|
||||
pub schema: String,
|
||||
pub redis_key_prefix: String,
|
||||
pub clickhouse_database: String,
|
||||
}
|
||||
|
||||
impl storage_impl::config::TenantConfig for Tenant {
|
||||
@ -164,6 +166,12 @@ impl storage_impl::config::TenantConfig for Tenant {
|
||||
}
|
||||
}
|
||||
|
||||
impl storage_impl::config::ClickHouseConfig for Tenant {
|
||||
fn get_clickhouse_database(&self) -> &str {
|
||||
self.clickhouse_database.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
pub struct GlobalTenant {
|
||||
pub schema: String,
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use common_utils::consts::TENANT_HEADER;
|
||||
use futures::StreamExt;
|
||||
use router_env::{
|
||||
logger,
|
||||
@ -140,10 +141,17 @@ where
|
||||
// TODO: have a common source of truth for the list of top level fields
|
||||
// /crates/router_env/src/logger/storage.rs also has a list of fields called PERSISTENT_KEYS
|
||||
fn call(&self, req: actix_web::dev::ServiceRequest) -> Self::Future {
|
||||
let tenant_id = req
|
||||
.headers()
|
||||
.get(TENANT_HEADER)
|
||||
.and_then(|i| i.to_str().ok())
|
||||
.map(|s| s.to_owned());
|
||||
let response_fut = self.service.call(req);
|
||||
|
||||
Box::pin(
|
||||
async move {
|
||||
if let Some(tenant_id) = tenant_id {
|
||||
router_env::tracing::Span::current().record("tenant_id", &tenant_id);
|
||||
}
|
||||
let response = response_fut.await;
|
||||
router_env::tracing::Span::current().record("golden_log_line", true);
|
||||
response
|
||||
|
||||
@ -5,7 +5,6 @@ use actix_web::{web, Scope};
|
||||
use api_models::routing::RoutingRetrieveQuery;
|
||||
#[cfg(feature = "olap")]
|
||||
use common_enums::TransactionType;
|
||||
use common_utils::consts::{DEFAULT_TENANT, GLOBAL_TENANT};
|
||||
#[cfg(feature = "email")]
|
||||
use external_services::email::{ses::AwsSes, EmailService};
|
||||
use external_services::file_storage::FileStorageInterface;
|
||||
@ -257,19 +256,11 @@ impl AppState {
|
||||
let cache_store = get_cache_store(&conf.clone(), shut_down_signal, testable)
|
||||
.await
|
||||
.expect("Failed to create store");
|
||||
let global_tenant = if conf.multitenancy.enabled {
|
||||
GLOBAL_TENANT
|
||||
} else {
|
||||
DEFAULT_TENANT
|
||||
};
|
||||
let global_store: Box<dyn GlobalStorageInterface> = Self::get_store_interface(
|
||||
&storage_impl,
|
||||
&event_handler,
|
||||
&conf,
|
||||
&settings::GlobalTenant {
|
||||
schema: global_tenant.to_string(),
|
||||
redis_key_prefix: String::default(),
|
||||
},
|
||||
&conf.multitenancy.global_tenant,
|
||||
Arc::clone(&cache_store),
|
||||
testable,
|
||||
)
|
||||
@ -288,9 +279,7 @@ impl AppState {
|
||||
.get_storage_interface();
|
||||
stores.insert(tenant_name.clone(), store);
|
||||
#[cfg(feature = "olap")]
|
||||
let pool =
|
||||
AnalyticsProvider::from_conf(conf.analytics.get_inner(), tenant_name.as_str())
|
||||
.await;
|
||||
let pool = AnalyticsProvider::from_conf(conf.analytics.get_inner(), tenant).await;
|
||||
#[cfg(feature = "olap")]
|
||||
pools.insert(tenant_name.clone(), pool);
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ use api_models::enums::{CaptureMethod, PaymentMethodType};
|
||||
pub use client::{proxy_bypass_urls, ApiClient, MockApiClient, ProxyClient};
|
||||
pub use common_utils::request::{ContentType, Method, Request, RequestBuilder};
|
||||
use common_utils::{
|
||||
consts::X_HS_LATENCY,
|
||||
consts::{DEFAULT_TENANT, TENANT_HEADER, X_HS_LATENCY},
|
||||
errors::{ErrorSwitch, ReportSwitchExt},
|
||||
request::RequestContent,
|
||||
};
|
||||
@ -783,10 +783,10 @@ where
|
||||
.into_iter()
|
||||
.collect();
|
||||
let tenant_id = if !state.conf.multitenancy.enabled {
|
||||
common_utils::consts::DEFAULT_TENANT.to_string()
|
||||
DEFAULT_TENANT.to_string()
|
||||
} else {
|
||||
incoming_request_header
|
||||
.get("x-tenant-id")
|
||||
.get(TENANT_HEADER)
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.ok_or_else(|| errors::ApiErrorResponse::MissingTenantId.switch())
|
||||
.map(|req_tenant_id| {
|
||||
|
||||
Reference in New Issue
Block a user