nifi_rust_client/
builder.rs1#![deny(missing_docs)]
2use std::sync::Arc;
3use std::time::Duration;
4
5use snafu::ResultExt as _;
6use url::Url;
7
8use crate::NifiClient;
9use crate::NifiError;
10use crate::config::auth::AuthProvider;
11use crate::error::{HttpSnafu, InvalidBaseUrlSnafu, InvalidCertificateSnafu};
12
13pub struct NifiClientBuilder {
37 base_url: Url,
38 timeout: Option<Duration>,
39 connect_timeout: Option<Duration>,
40 proxy_all: Option<Url>,
41 proxy_http: Option<Url>,
42 proxy_https: Option<Url>,
43 danger_accept_invalid_certs: bool,
44 root_certificates: Vec<Vec<u8>>,
45 auth_provider: Option<Arc<dyn AuthProvider>>,
46 client_identity: Option<reqwest::Identity>,
47 proxied_entities_chain: Option<String>,
48 retry_policy: Option<crate::config::retry::RetryPolicy>,
49 request_id_header: Option<String>,
50 #[cfg(feature = "dynamic")]
51 version_strategy: Option<crate::dynamic::VersionResolutionStrategy>,
52}
53
54impl std::fmt::Debug for NifiClientBuilder {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 let mut s = f.debug_struct("NifiClientBuilder");
57 s.field("base_url", &self.base_url)
58 .field("timeout", &self.timeout)
59 .field("connect_timeout", &self.connect_timeout)
60 .field("proxy_all", &self.proxy_all)
61 .field("proxy_http", &self.proxy_http)
62 .field("proxy_https", &self.proxy_https)
63 .field(
64 "danger_accept_invalid_certs",
65 &self.danger_accept_invalid_certs,
66 )
67 .field(
68 "root_certificates",
69 &format!("[{} certs]", self.root_certificates.len()),
70 )
71 .field(
72 "auth_provider",
73 &self.auth_provider.as_ref().map(|c| format!("{c:?}")),
74 )
75 .field(
76 "client_identity",
77 &self.client_identity.as_ref().map(|_| "<identity>"),
78 )
79 .field("proxied_entities_chain", &self.proxied_entities_chain)
80 .field("retry_policy", &self.retry_policy)
81 .field("request_id_header", &self.request_id_header);
82 #[cfg(feature = "dynamic")]
83 s.field("version_strategy", &self.version_strategy);
84 s.finish()
85 }
86}
87
88impl NifiClientBuilder {
89 pub fn new(base_url: &str) -> Result<Self, NifiError> {
93 let base_url = Url::parse(base_url).context(InvalidBaseUrlSnafu)?;
94 Ok(Self {
95 base_url,
96 timeout: None,
97 connect_timeout: None,
98 proxy_all: None,
99 proxy_http: None,
100 proxy_https: None,
101 danger_accept_invalid_certs: false,
102 root_certificates: Vec::new(),
103 auth_provider: None,
104 client_identity: None,
105 proxied_entities_chain: None,
106 retry_policy: None,
107 request_id_header: None,
108 #[cfg(feature = "dynamic")]
109 version_strategy: None,
110 })
111 }
112
113 pub fn timeout(mut self, duration: Duration) -> Self {
118 self.timeout = Some(duration);
119 self
120 }
121
122 pub fn connect_timeout(mut self, duration: Duration) -> Self {
124 self.connect_timeout = Some(duration);
125 self
126 }
127
128 pub fn proxy(mut self, url: Url) -> Self {
130 self.proxy_all = Some(url);
131 self
132 }
133
134 pub fn http_proxy(mut self, url: Url) -> Self {
136 self.proxy_http = Some(url);
137 self
138 }
139
140 pub fn https_proxy(mut self, url: Url) -> Self {
142 self.proxy_https = Some(url);
143 self
144 }
145
146 pub fn danger_accept_invalid_certs(mut self, accept: bool) -> Self {
150 self.danger_accept_invalid_certs = accept;
151 self
152 }
153
154 pub fn add_root_certificate(mut self, pem: &[u8]) -> Self {
158 self.root_certificates.push(pem.to_vec());
159 self
160 }
161
162 pub fn auth_provider(mut self, provider: impl AuthProvider + 'static) -> Self {
167 self.auth_provider = Some(Arc::new(provider));
168 self
169 }
170
171 pub fn client_identity_pem(mut self, pem: &[u8]) -> Result<Self, NifiError> {
177 let identity = reqwest::Identity::from_pem(pem).context(InvalidCertificateSnafu)?;
178 self.client_identity = Some(identity);
179 Ok(self)
180 }
181
182 pub fn proxied_entities_chain(mut self, chain: impl Into<String>) -> Self {
187 self.proxied_entities_chain = Some(chain.into());
188 self
189 }
190
191 pub fn retry_policy(mut self, policy: crate::config::retry::RetryPolicy) -> Self {
196 self.retry_policy = Some(policy);
197 self
198 }
199
200 pub fn request_id_header(mut self, name: Option<impl Into<String>>) -> Self {
211 self.request_id_header = name.map(Into::into);
212 self
213 }
214
215 #[cfg(feature = "dynamic")]
221 pub fn version_strategy(mut self, strategy: crate::dynamic::VersionResolutionStrategy) -> Self {
222 self.version_strategy = Some(strategy);
223 self
224 }
225
226 pub fn build(self) -> Result<NifiClient, NifiError> {
228 let mut builder = reqwest::Client::builder()
229 .danger_accept_invalid_certs(self.danger_accept_invalid_certs);
230
231 if let Some(d) = self.timeout {
232 builder = builder.timeout(d);
233 }
234 if let Some(d) = self.connect_timeout {
235 builder = builder.connect_timeout(d);
236 }
237
238 for pem in &self.root_certificates {
239 let cert = reqwest::Certificate::from_pem(pem).context(InvalidCertificateSnafu)?;
240 builder = builder.add_root_certificate(cert);
241 }
242
243 if let Some(url) = self.proxy_all {
244 let proxy = reqwest::Proxy::all(url.as_str()).context(HttpSnafu)?;
245 builder = builder.proxy(proxy);
246 }
247 if let Some(url) = self.proxy_http {
248 let proxy = reqwest::Proxy::http(url.as_str()).context(HttpSnafu)?;
249 builder = builder.proxy(proxy);
250 }
251 if let Some(url) = self.proxy_https {
252 let proxy = reqwest::Proxy::https(url.as_str()).context(HttpSnafu)?;
253 builder = builder.proxy(proxy);
254 }
255
256 if let Some(identity) = self.client_identity {
257 builder = builder.identity(identity);
258 }
259
260 let http = builder.build().context(HttpSnafu)?;
261 Ok(NifiClient::from_parts(
262 self.base_url,
263 http,
264 self.auth_provider,
265 self.proxied_entities_chain,
266 self.retry_policy,
267 self.request_id_header,
268 ))
269 }
270
271 #[cfg(feature = "dynamic")]
297 pub fn build_dynamic(self) -> Result<crate::dynamic::DynamicClient, NifiError> {
298 let strategy = self.version_strategy.unwrap_or_default();
299 let client = self.build()?;
300 Ok(crate::dynamic::DynamicClient::with_strategy(
301 client, strategy,
302 ))
303 }
304}