meta_srv/service/admin/
node_lease.rs1use std::collections::HashMap;
16
17use axum::Json;
18use axum::extract::State;
19use axum::response::{IntoResponse, Response};
20use serde::{Deserialize, Serialize};
21use snafu::ResultExt;
22use tonic::codegen::http;
23
24use crate::cluster::MetaPeerClientRef;
25use crate::discovery::lease::{LeaseValueAccessor, LeaseValueType};
26use crate::error::{self, Result};
27use crate::key::{DatanodeLeaseKey, LeaseValue};
28use crate::service::admin::HttpHandler;
29use crate::service::admin::util::ErrorHandler;
30
31#[derive(Clone)]
32pub struct NodeLeaseHandler {
33 pub meta_peer_client: MetaPeerClientRef,
34}
35
36impl NodeLeaseHandler {
37 async fn get_node_lease(&self) -> Result<LeaseValues> {
38 let leases = self
39 .meta_peer_client
40 .lease_values(LeaseValueType::Datanode)
41 .await?
42 .into_iter()
43 .collect::<HashMap<_, _>>();
44
45 let leases = leases
46 .into_iter()
47 .map(|(k, v)| HumanLease {
48 name: DatanodeLeaseKey { node_id: k },
49 human_time: common_time::Timestamp::new_millisecond(v.timestamp_millis)
50 .to_local_string(),
51 lease: v,
52 })
53 .collect::<Vec<_>>();
54 Ok(LeaseValues { leases })
55 }
56}
57
58#[axum_macros::debug_handler]
60pub(crate) async fn get(State(handler): State<NodeLeaseHandler>) -> Response {
61 handler
62 .get_node_lease()
63 .await
64 .map_err(ErrorHandler::new)
65 .map(Json)
66 .into_response()
67}
68
69#[async_trait::async_trait]
70impl HttpHandler for NodeLeaseHandler {
71 async fn handle(
72 &self,
73 _: &str,
74 _: http::Method,
75 _: &HashMap<String, String>,
76 ) -> Result<http::Response<String>> {
77 let result = self.get_node_lease().await?.try_into()?;
78
79 http::Response::builder()
80 .status(http::StatusCode::OK)
81 .body(result)
82 .context(error::InvalidHttpBodySnafu)
83 }
84}
85
86#[derive(Debug, Serialize, Deserialize)]
87pub struct HumanLease {
88 pub name: DatanodeLeaseKey,
89 pub human_time: String,
90 pub lease: LeaseValue,
91}
92
93#[derive(Debug, Serialize, Deserialize)]
94#[serde(transparent)]
95pub struct LeaseValues {
96 pub leases: Vec<HumanLease>,
97}
98
99impl TryFrom<LeaseValues> for String {
100 type Error = error::Error;
101
102 fn try_from(vals: LeaseValues) -> Result<Self> {
103 serde_json::to_string(&vals).context(error::SerializeToJsonSnafu {
104 input: format!("{vals:?}"),
105 })
106 }
107}