use axum::extract::State;
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::Json;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct ReadyResponse {
pub status: &'static str,
}
impl ReadyResponse {
pub const fn ready() -> Self {
Self { status: "ready" }
}
pub const fn not_ready(reason: &'static str) -> Self {
Self { status: reason }
}
}
#[tracing::instrument(skip_all)]
pub async fn handle(state: State<super::RouterState>) -> impl IntoResponse {
if state.ready_status.is_ready() {
(StatusCode::OK, Json(ReadyResponse::ready()))
} else {
(
StatusCode::SERVICE_UNAVAILABLE,
Json(ReadyResponse::not_ready(state.ready_status.reason())),
)
}
}
pub fn register_routes(
router: axum::Router<super::RouterState>,
) -> axum::Router<super::RouterState> {
router.route("/ready", axum::routing::get(handle))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ready_response_ready() {
let response = ReadyResponse::ready();
assert_eq!(response.status, "ready");
}
#[test]
fn test_ready_response_not_ready() {
let response =
ReadyResponse::not_ready(crate::bootstrap::ReadyStatus::REASON_BOOTSTRAP_INCOMPLETE);
assert_eq!(response.status, crate::bootstrap::ReadyStatus::REASON_BOOTSTRAP_INCOMPLETE);
}
#[test]
fn test_ready_response_serialization_ready() {
let response = ReadyResponse::ready();
let json = serde_json::to_string(&response).expect("serialization should succeed");
assert_eq!(json, r#"{"status":"ready"}"#);
}
#[test]
fn test_ready_response_serialization_not_ready() {
let response =
ReadyResponse::not_ready(crate::bootstrap::ReadyStatus::REASON_BOOTSTRAP_INCOMPLETE);
let json = serde_json::to_string(&response).expect("serialization should succeed");
assert_eq!(json, r#"{"status":"bootstrap_incomplete"}"#);
}
#[test]
fn test_ready_response_from_ready_status_ready() {
let ready_status = crate::bootstrap::ReadyStatus::ready();
let response = if ready_status.is_ready() {
ReadyResponse::ready()
} else {
ReadyResponse::not_ready(ready_status.reason())
};
assert_eq!(response.status, "ready");
}
#[test]
fn test_ready_response_from_ready_status_not_ready() {
let ready_status = crate::bootstrap::ReadyStatus::not_ready(
crate::bootstrap::ReadyStatus::REASON_BOOTSTRAP_INCOMPLETE,
);
let response = if ready_status.is_ready() {
ReadyResponse::ready()
} else {
ReadyResponse::not_ready(ready_status.reason())
};
assert_eq!(response.status, crate::bootstrap::ReadyStatus::REASON_BOOTSTRAP_INCOMPLETE);
}
}