arangors_graph_exporter/client/
builder.rs1use crate::DatabaseConfiguration;
2use crate::client::config::ClientConfig;
3use reqwest::{Certificate, Client};
4use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
5use reqwest_retry::RetryTransientMiddleware;
6use reqwest_retry::policies::ExponentialBackoff;
7use std::fs::File;
8use std::io::Read;
9
10pub fn make_url(db_config: &DatabaseConfiguration, path: &str) -> String {
11 db_config.endpoints[0].clone() + "/_db/" + &db_config.database + path
12}
13
14pub fn build_client(
15 config: &ClientConfig,
16) -> Result<reqwest_middleware::ClientWithMiddleware, String> {
17 let mut client_builder = reqwest::Client::builder();
18 client_builder = if config.use_tls {
19 client_builder = client_builder
20 .min_tls_version(reqwest::tls::Version::TLS_1_2)
21 .https_only(true);
22
23 if let Some(cert_path) = &config.tls_cert {
24 let cert = get_cert(cert_path)?;
25 client_builder.add_root_certificate(cert).use_rustls_tls()
26 } else {
27 client_builder
28 .danger_accept_invalid_certs(true)
29 .use_rustls_tls()
30 }
31 } else {
32 client_builder.danger_accept_invalid_certs(true)
33 };
34 let client = client_builder
35 .build()
36 .map_err(|err| format!("Error message from request builder: {:?}", err))?;
37 let client = client_with_retries(&config.n_retries, client);
38 Ok(client)
39}
40
41fn get_cert(cert_path: &String) -> Result<Certificate, String> {
42 if cert_path.is_empty() {
43 return Err(
44 "Error message from reading TLS certificate: Certificate path is empty".to_string(),
45 );
46 }
47 let mut cert_buf = vec![];
48 let mut file = File::open(cert_path)
49 .map_err(|err| format!("Error message from reading TLS certificate: {:?}", err))?;
50 file.read_to_end(&mut cert_buf)
51 .map_err(|err| format!("Error message from reading TLS certificate: {:?}", err))?;
52 let cert = reqwest::Certificate::from_pem(&cert_buf)
53 .map_err(|err| format!("Error message from request builder: {:?}", err))?;
54 Ok(cert)
55}
56
57fn client_with_retries(n_retries: &u32, client: Client) -> ClientWithMiddleware {
58 let retry_policy = ExponentialBackoff::builder()
59 .retry_bounds(
60 std::time::Duration::from_millis(30),
61 std::time::Duration::from_millis(3000),
62 )
63 .build_with_max_retries(*n_retries);
64 let retry_middleware = RetryTransientMiddleware::new_with_policy(retry_policy);
65 ClientBuilder::new(client).with(retry_middleware).build()
66}