use crate::default_token_factory::DefaultTokenFactory;
use crate::token_cache::{TokenCache, DEFAULT_REFRESH_BUFFER};
use crate::ZerobusResult;
use async_trait::async_trait;
use std::collections::HashMap;
use std::sync::Arc;
#[async_trait]
pub trait HeadersProvider: Send + Sync {
async fn get_headers(&self) -> ZerobusResult<HashMap<&'static str, String>>;
async fn invalidate(&self) {}
}
pub struct OAuthHeadersProvider {
client_id: String,
client_secret: String,
table_name: String,
workspace_id: String,
unity_catalog_url: String,
token_cache: Arc<TokenCache>,
}
impl OAuthHeadersProvider {
pub fn new(
client_id: String,
client_secret: String,
table_name: String,
workspace_id: String,
unity_catalog_url: String,
) -> Self {
Self::with_cache(
client_id,
client_secret,
table_name,
workspace_id,
unity_catalog_url,
Arc::new(TokenCache::new(true, DEFAULT_REFRESH_BUFFER)),
)
}
pub(crate) fn with_cache(
client_id: String,
client_secret: String,
table_name: String,
workspace_id: String,
unity_catalog_url: String,
token_cache: Arc<TokenCache>,
) -> Self {
Self {
client_id,
client_secret,
table_name,
workspace_id,
unity_catalog_url,
token_cache,
}
}
}
#[async_trait]
impl HeadersProvider for OAuthHeadersProvider {
async fn get_headers(&self) -> ZerobusResult<HashMap<&'static str, String>> {
let token = self
.token_cache
.get_or_fetch(
&self.client_id,
&self.client_secret,
&self.table_name,
|reason| {
DefaultTokenFactory::fetch_token(
&self.unity_catalog_url,
&self.table_name,
&self.client_id,
&self.client_secret,
&self.workspace_id,
reason,
)
},
)
.await?;
let mut headers = HashMap::new();
headers.insert("authorization", format!("Bearer {}", token));
headers.insert("x-databricks-zerobus-table-name", self.table_name.clone());
Ok(headers)
}
async fn invalidate(&self) {
self.token_cache
.invalidate(&self.client_id, &self.client_secret, &self.table_name)
.await;
}
}
#[cfg(feature = "testing")]
pub struct NoAuthHeadersProvider;
#[cfg(feature = "testing")]
#[async_trait]
impl HeadersProvider for NoAuthHeadersProvider {
async fn get_headers(&self) -> ZerobusResult<HashMap<&'static str, String>> {
Ok(HashMap::new())
}
}