feat: http api for node-lease (#1843)

* feat: add node-lease http api

* revert: show_create.result
This commit is contained in:
JeremyHi
2023-06-29 09:34:54 +08:00
committed by GitHub
parent 559d1f73a2
commit 7e23dd7714
3 changed files with 99 additions and 2 deletions

View File

@@ -36,7 +36,8 @@ lazy_static! {
static ref DATANODE_STAT_KEY_PATTERN: Regex =
Regex::new(&format!("^{DN_STAT_PREFIX}-([0-9]+)-([0-9]+)$")).unwrap();
}
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct LeaseKey {
pub cluster_id: u64,
pub node_id: u64,

View File

@@ -16,6 +16,7 @@ mod health;
mod heartbeat;
mod leader;
mod meta;
mod node_lease;
mod route;
use std::collections::HashMap;
@@ -32,6 +33,13 @@ use crate::metasrv::MetaSrv;
pub fn make_admin_service(meta_srv: MetaSrv) -> Admin {
let router = Router::new().route("/health", health::HealthHandler);
let router = router.route(
"/node-lease",
node_lease::NodeLeaseHandler {
meta_peer_client: meta_srv.meta_peer_client(),
},
);
let router = router.route(
"/heartbeat",
heartbeat::HeartBeatHandler {
@@ -119,7 +127,7 @@ impl<T> Service<http::Request<T>> for Admin
where
T: Send,
{
type Response = http::Response<tonic::body::BoxBody>;
type Response = http::Response<BoxBody>;
type Error = Infallible;
type Future = BoxFuture<Self::Response, Self::Error>;

View File

@@ -0,0 +1,88 @@
// Copyright 2023 Greptime Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use snafu::{OptionExt, ResultExt};
use tonic::codegen::http;
use crate::cluster::MetaPeerClientRef;
use crate::error::{self, Result};
use crate::keys::{LeaseKey, LeaseValue};
use crate::lease;
use crate::service::admin::HttpHandler;
pub struct NodeLeaseHandler {
pub meta_peer_client: MetaPeerClientRef,
}
#[async_trait::async_trait]
impl HttpHandler for NodeLeaseHandler {
async fn handle(
&self,
_: &str,
params: &HashMap<String, String>,
) -> Result<http::Response<String>> {
let cluster_id = params
.get("cluster_id")
.map(|id| id.parse::<u64>())
.context(error::MissingRequiredParameterSnafu {
param: "cluster_id",
})?
.context(error::ParseNumSnafu {
err_msg: "`cluster_id` is not a valid number",
})?;
let leases =
lease::filter_datanodes(cluster_id, &self.meta_peer_client, |_, _| true).await?;
let leases = leases
.into_iter()
.map(|(k, v)| HumanLease {
name: k,
human_time: common_time::DateTime::new(v.timestamp_millis / 1000).to_string(),
lease: v,
})
.collect::<Vec<_>>();
let result = LeaseValues { leases }.try_into()?;
http::Response::builder()
.status(http::StatusCode::OK)
.body(result)
.context(error::InvalidHttpBodySnafu)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct HumanLease {
pub name: LeaseKey,
pub human_time: String,
pub lease: LeaseValue,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct LeaseValues {
pub leases: Vec<HumanLease>,
}
impl TryFrom<LeaseValues> for String {
type Error = error::Error;
fn try_from(vals: LeaseValues) -> Result<Self> {
serde_json::to_string(&vals).context(error::SerializeToJsonSnafu {
input: format!("{vals:?}"),
})
}
}