Line data Source code
1 : use pageserver_client::mgmt_api::{self, ResponseErrorMessageExt};
2 : use reqwest::{Method, Url};
3 : use serde::{de::DeserializeOwned, Serialize};
4 :
5 : pub struct Client {
6 : base_url: Url,
7 : jwt_token: Option<String>,
8 : client: reqwest::Client,
9 : }
10 :
11 : impl Client {
12 0 : pub fn new(base_url: Url, jwt_token: Option<String>) -> Self {
13 0 : Self {
14 0 : base_url,
15 0 : jwt_token,
16 0 : client: reqwest::ClientBuilder::new()
17 0 : .build()
18 0 : .expect("Failed to construct http client"),
19 0 : }
20 0 : }
21 :
22 : /// Simple HTTP request wrapper for calling into storage controller
23 0 : pub async fn dispatch<RQ, RS>(
24 0 : &self,
25 0 : method: Method,
26 0 : path: String,
27 0 : body: Option<RQ>,
28 0 : ) -> mgmt_api::Result<RS>
29 0 : where
30 0 : RQ: Serialize + Sized,
31 0 : RS: DeserializeOwned + Sized,
32 0 : {
33 0 : let request_path = self
34 0 : .base_url
35 0 : .join(&path)
36 0 : .expect("Failed to build request path");
37 0 : let mut builder = self.client.request(method, request_path);
38 0 : if let Some(body) = body {
39 0 : builder = builder.json(&body)
40 0 : }
41 0 : if let Some(jwt_token) = &self.jwt_token {
42 0 : builder = builder.header(
43 0 : reqwest::header::AUTHORIZATION,
44 0 : format!("Bearer {jwt_token}"),
45 0 : );
46 0 : }
47 :
48 0 : let response = builder.send().await.map_err(mgmt_api::Error::ReceiveBody)?;
49 0 : let response = response.error_from_body().await?;
50 :
51 0 : response
52 0 : .json()
53 0 : .await
54 0 : .map_err(pageserver_client::mgmt_api::Error::ReceiveBody)
55 0 : }
56 : }
|