Skip to content

Commit

Permalink
feat: http api for node-lease (#1843)
Browse files Browse the repository at this point in the history
* feat: add node-lease http api

* revert: show_create.result
  • Loading branch information
fengjiachun authored Jun 29, 2023
1 parent 559d1f7 commit 7e23dd7
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/meta-srv/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 9 additions & 1 deletion src/meta-srv/src/service/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod health;
mod heartbeat;
mod leader;
mod meta;
mod node_lease;
mod route;

use std::collections::HashMap;
Expand All @@ -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 {
Expand Down Expand Up @@ -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>;

Expand Down
88 changes: 88 additions & 0 deletions src/meta-srv/src/service/admin/node_lease.rs
Original file line number Diff line number Diff line change
@@ -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:?}"),
})
}
}

0 comments on commit 7e23dd7

Please sign in to comment.