use std::time::Duration;
use once_cell::sync::Lazy;
use reqwest::Url;
use reqwest_retry::policies::ExponentialBackoff;
use reqwest_retry::RetryTransientMiddleware;
use crate::client::Client;
pub static DEFAULT_VENDOR_ENDPOINT: Lazy<Url> = Lazy::new(|| {
"https://api.frontegg.com"
.parse()
.expect("url known to be valid")
});
pub struct ClientConfig {
pub client_id: String,
pub secret_key: String,
}
pub struct ClientBuilder {
vendor_endpoint: Url,
retry_policy: Option<ExponentialBackoff>,
}
impl Default for ClientBuilder {
fn default() -> ClientBuilder {
ClientBuilder {
vendor_endpoint: DEFAULT_VENDOR_ENDPOINT.clone(),
retry_policy: Some(
ExponentialBackoff::builder()
.retry_bounds(Duration::from_millis(100), Duration::from_secs(3))
.build_with_max_retries(5),
),
}
}
}
impl ClientBuilder {
pub fn with_retry_policy(mut self, policy: ExponentialBackoff) -> Self {
self.retry_policy = Some(policy);
self
}
pub fn with_vendor_endpoint(mut self, endpoint: Url) -> Self {
self.vendor_endpoint = endpoint;
self
}
pub fn build(self, config: ClientConfig) -> Client {
let client = reqwest::ClientBuilder::new()
.redirect(reqwest::redirect::Policy::none())
.timeout(Duration::from_secs(60))
.build()
.unwrap();
Client {
client_retryable: match self.retry_policy {
Some(policy) => reqwest_middleware::ClientBuilder::new(client.clone())
.with(RetryTransientMiddleware::new_with_policy(policy))
.build(),
None => reqwest_middleware::ClientBuilder::new(client.clone()).build(),
},
client_non_retryable: reqwest_middleware::ClientBuilder::new(client).build(),
client_id: config.client_id,
secret_key: config.secret_key,
vendor_endpoint: self.vendor_endpoint,
auth: Default::default(),
}
}
}