add new endpoints for health and build information

This commit is contained in:
Jędrzej Stuczyński
2025-03-12 09:06:07 +00:00
parent a7fcfef5a3
commit 900c44da59
7 changed files with 140 additions and 15 deletions
Generated
+1 -1
View File
@@ -7233,7 +7233,7 @@ dependencies = [
[[package]]
name = "nyx-chain-watcher"
version = "0.1.13"
version = "0.1.14"
dependencies = [
"anyhow",
"async-trait",
+38
View File
@@ -1185,6 +1185,7 @@ name = "nym-pemstore"
version = "0.3.0"
dependencies = [
"pem",
"tracing",
]
[[package]]
@@ -1251,6 +1252,12 @@ dependencies = [
"regex",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pkcs8"
version = "0.9.0"
@@ -1840,6 +1847,37 @@ dependencies = [
"winnow",
]
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "tracing-core"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
dependencies = [
"once_cell",
]
[[package]]
name = "typenum"
version = "1.18.0"
+4 -4
View File
@@ -4783,9 +4783,9 @@ dependencies = [
[[package]]
name = "rs_merkle"
version = "1.4.2"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b241d2e59b74ef9e98d94c78c47623d04c8392abaf82014dfd372a16041128f"
checksum = "bb09b49230ba22e8c676e7b75dfe2887dea8121f18b530ae0ba519ce442d2b21"
dependencies = [
"sha2 0.10.8",
]
@@ -6114,9 +6114,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.43.0"
version = "1.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a"
dependencies = [
"backtrace",
"bytes",
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nyx-chain-watcher"
version = "0.1.13"
version = "0.1.14"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
+38 -3
View File
@@ -2,21 +2,56 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::http::models::status::{
ActivePaymentWatchersResponse, PaymentListenerFailureDetails, PaymentListenerStatusResponse,
ProcessedPayment, WatcherFailureDetails, WatcherState,
ActivePaymentWatchersResponse, ApiStatus, HealthResponse, PaymentListenerFailureDetails,
PaymentListenerStatusResponse, ProcessedPayment, WatcherFailureDetails, WatcherState,
};
use crate::http::state::{AppState, PaymentListenerState};
use crate::http::state::{AppState, PaymentListenerState, StatusState};
use axum::extract::State;
use axum::routing::get;
use axum::{Json, Router};
use nym_bin_common::build_information::BinaryBuildInformationOwned;
use std::ops::Deref;
pub(crate) fn routes() -> Router<AppState> {
Router::new()
.route("/health", get(health))
.route("/build-information", get(build_information))
.route("/active-payment-watchers", get(active_payment_watchers))
.route("/payment-listener", get(payment_listener_status))
}
#[utoipa::path(
tag = "Status",
get,
path = "/build-information",
context_path = "/v1/status",
responses(
(status = 200, body = BinaryBuildInformationOwned)
)
)]
async fn build_information(State(state): State<StatusState>) -> Json<BinaryBuildInformationOwned> {
Json(state.build_information.to_owned())
}
#[utoipa::path(
tag = "Status",
get,
path = "/health",
context_path = "/v1/status",
responses(
(status = 200, body = HealthResponse)
)
)]
async fn health(State(state): State<StatusState>) -> Json<HealthResponse> {
let uptime = state.startup_time.elapsed();
let health = HealthResponse {
status: ApiStatus::Up,
uptime: uptime.as_secs(),
};
Json(health)
}
#[utoipa::path(
tag = "Status",
get,
+12
View File
@@ -12,6 +12,18 @@ pub mod status {
use time::OffsetDateTime;
use utoipa::ToSchema;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum ApiStatus {
Up,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
pub struct HealthResponse {
pub status: ApiStatus,
pub uptime: u64,
}
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ActivePaymentWatchersResponse {
pub watchers: Vec<PaymentWatcher>,
+46 -6
View File
@@ -3,18 +3,23 @@ use crate::helpers::RingBuffer;
use crate::http::models::status::PaymentWatcher;
use crate::models::WebhookPayload;
use axum::extract::FromRef;
use nym_bin_common::bin_info;
use nym_bin_common::build_information::BinaryBuildInformation;
use nym_validator_client::nyxd::Coin;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::ops::Deref;
use std::sync::Arc;
use time::OffsetDateTime;
use tokio::sync::RwLock;
use tokio::time::Instant;
#[derive(Debug, Clone)]
pub(crate) struct AppState {
db_pool: DbPool,
pub(crate) registered_payment_watchers: Arc<Vec<PaymentWatcher>>,
pub(crate) payment_listener_state: PaymentListenerState,
pub(crate) status_state: StatusState,
}
impl AppState {
@@ -27,6 +32,7 @@ impl AppState {
db_pool,
registered_payment_watchers: Arc::new(registered_payment_watchers),
payment_listener_state,
status_state: Default::default(),
}
}
@@ -43,6 +49,35 @@ impl AppState {
}
}
#[derive(Clone, Debug)]
pub(crate) struct StatusState {
inner: Arc<StatusStateInner>,
}
impl Default for StatusState {
fn default() -> Self {
StatusState {
inner: Arc::new(StatusStateInner {
startup_time: Instant::now(),
build_information: bin_info!(),
}),
}
}
}
impl Deref for StatusState {
type Target = StatusStateInner;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Debug)]
pub(crate) struct StatusStateInner {
pub(crate) startup_time: Instant,
pub(crate) build_information: BinaryBuildInformation,
}
#[derive(Debug, Clone)]
pub(crate) struct PaymentListenerState {
pub(crate) inner: Arc<RwLock<PaymentListenerStateInner>>,
@@ -99,12 +134,6 @@ impl PaymentListenerState {
}
}
impl FromRef<AppState> for PaymentListenerState {
fn from_ref(input: &AppState) -> Self {
input.payment_listener_state.clone()
}
}
#[derive(Debug)]
pub(crate) struct PaymentListenerStateInner {
pub(crate) last_checked: OffsetDateTime,
@@ -181,3 +210,14 @@ impl WatcherFailureDetails {
}
}
}
impl FromRef<AppState> for PaymentListenerState {
fn from_ref(input: &AppState) -> Self {
input.payment_listener_state.clone()
}
}
impl FromRef<AppState> for StatusState {
fn from_ref(input: &AppState) -> Self {
input.status_state.clone()
}
}