From 7aebbca98d94e399de36ed3b0f16212fd5ec40fd Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 26 Aug 2025 11:16:33 +0200 Subject: [PATCH] feat(health): add /health endpoint + tests + docs --- docs/api_json_spec.md | 4 ++++ docs/tests_monitoring.md | 3 ++- src/lib.rs | 7 +++++++ tests/http_api.rs | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/api_json_spec.md b/docs/api_json_spec.md index 0920469..550002e 100644 --- a/docs/api_json_spec.md +++ b/docs/api_json_spec.md @@ -68,6 +68,10 @@ ``` ## GET /retrieve/:key +## GET /health +- Aucune donnée d'entrée. +- Réponse 200 avec `ApiResponse` `{ "message": "ok" }`. + - Paramètre de chemin: `key` (hex 64). - Objet réponse (succès): `RetrieveResponse` - Objet réponse (erreur): `ApiResponse` diff --git a/docs/tests_monitoring.md b/docs/tests_monitoring.md index 3509f2a..7b2a501 100644 --- a/docs/tests_monitoring.md +++ b/docs/tests_monitoring.md @@ -4,5 +4,6 @@ - Unitaires et intégration via `cargo test`. ## Monitoring +- Healthcheck HTTP: endpoint `/health` retourne `{ "message": "ok" }` et code 200. - Exposer métriques avec un reverse proxy/sidecar si nécessaire. -- Ajouter des healthchecks HTTP au niveau de l'orchestrateur. +- Configurer l'orchestrateur pour vérifier périodiquement `/health`. diff --git a/src/lib.rs b/src/lib.rs index a415121..3973535 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -156,6 +156,12 @@ pub struct ApiResponse { pub message: String } #[derive(Serialize)] pub struct RetrieveResponse { pub key: String, pub value: String } +pub async fn handle_health(_req: Request) -> tide::Result { + Ok(Response::builder(StatusCode::Ok) + .body(serde_json::to_value(&ApiResponse { message: "ok".into() })?) + .build()) +} + pub async fn handle_store(mut req: Request, no_ttl_permanent: bool) -> tide::Result { let data: StoreRequest = match req.body_json().await { Ok(data) => data, @@ -246,6 +252,7 @@ pub async fn handle_retrieve(req: Request) -> tide::Result) -> tide::Server { let svc = StorageService::new(storage_dir); let mut app = tide::with_state(svc); + app.at("/health").get(handle_health); app.at("/store").post(move |req| handle_store(req, no_ttl_permanent)); app.at("/retrieve/:key").get(handle_retrieve); app diff --git a/tests/http_api.rs b/tests/http_api.rs index fa16679..2e41498 100644 --- a/tests/http_api.rs +++ b/tests/http_api.rs @@ -116,3 +116,20 @@ async fn http_retrieve_success_and_invalid_and_notfound() { let res3 = client.get(format!("{}/retrieve/{}", base, k2)).await.unwrap(); assert_eq!(res3.status(), 404); } + +#[async_std::test] +async fn http_health_ok() { + let td = TempDir::new().unwrap(); + let storage = td.path().to_string_lossy().to_string(); + let mut app = create_app(true, storage); + let listener = async_std::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); + let addr = listener.local_addr().unwrap(); + async_std::task::spawn(async move { app.listen(listener).await.unwrap() }); + + let client = Client::new(); + let base = format!("http://{}", addr); + let mut res = client.get(format!("{}/health", base)).await.unwrap(); + assert!(res.status().is_success()); + let v: serde_json::Value = res.body_json().await.unwrap(); + assert_eq!(v["message"].as_str().unwrap(), "ok"); +}