Skip to content

Commit

Permalink
feat: [#508] add container healthcheck for API
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Nov 24, 2023
1 parent 0ef4e34 commit 48ac64f
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 8 deletions.
6 changes: 4 additions & 2 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ COPY --from=build \
RUN cargo nextest run --workspace-remap /test/src/ --extract-to /test/src/ --no-run --archive-file /test/torrust-tracker.tar.zst
RUN cargo nextest run --workspace-remap /test/src/ --target-dir-remap /test/src/target/ --cargo-metadata /test/src/target/nextest/cargo-metadata.json --binaries-metadata /test/src/target/nextest/binaries-metadata.json

RUN mkdir -p /app/bin/; cp -l /test/src/target/release/torrust-tracker /app/bin/torrust-tracker
RUN mkdir -p /app/bin/; cp -l /test/src/target/release/torrust-tracker /app/bin/torrust-tracker; cp -l /test/src/target/release/http_health_check /app/bin/http_health_check
RUN mkdir -p /app/lib/; cp -l $(realpath $(ldd /app/bin/torrust-tracker | grep "libz\.so\.1" | awk '{print $3}')) /app/lib/libz.so.1
RUN chown -R root:root /app; chmod -R u=rw,go=r,a+X /app; chmod -R a+x /app/bin

Expand Down Expand Up @@ -136,5 +136,7 @@ CMD ["sh"]
FROM runtime as release
ENV RUNTIME="release"
COPY --from=test /app/ /usr/
# HEALTHCHECK CMD ["/usr/bin/wget", "--no-verbose", "--tries=1", "--spider", "localhost:${API_PORT}/version"]
HEALTHCHECK --interval=5s --timeout=5s --start-period=3s --retries=3 \
CMD /usr/bin/http_health_check http://localhost:${API_PORT}/health_check \
|| exit 1
CMD ["/usr/bin/torrust-tracker"]
6 changes: 3 additions & 3 deletions src/bin/http_health_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use std::{env, process};
async fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: cargo run --bin health_check <HEALTH_URL>");
eprintln!("Example: cargo run --bin http_health_check http://localhost:1212/api/v1/stats?token=MyAccessToken");
eprintln!("Usage: cargo run --bin http_health_check <HEALTH_URL>");
eprintln!("Example: cargo run --bin http_health_check http://127.0.0.1:1212/health_check");
std::process::exit(1);
}

Expand All @@ -34,4 +34,4 @@ async fn main() {
process::exit(1);
}
}
}
}
7 changes: 5 additions & 2 deletions src/servers/apis/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,28 @@
//! first path segment. For example: `/api/v1/torrents`.
use std::sync::Arc;

use axum::routing::get;
use axum::{middleware, Router};
use tower_http::compression::CompressionLayer;

use super::v1;
use super::v1::context::health_check::handlers::health_check_handler;
use crate::tracker::Tracker;

/// Add all API routes to the router.
#[allow(clippy::needless_pass_by_value)]
pub fn router(tracker: Arc<Tracker>) -> Router {
let router = Router::new();

let prefix = "/api";
let api_url_prefix = "/api";

let router = v1::routes::add(prefix, router, tracker.clone());
let router = v1::routes::add(api_url_prefix, router, tracker.clone());

router
.layer(middleware::from_fn_with_state(
tracker.config.clone(),
v1::middlewares::auth::auth,
))
.route("/health_check", get(health_check_handler))
.layer(CompressionLayer::new())
}
11 changes: 11 additions & 0 deletions src/servers/apis/v1/context/health_check/handlers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! API handlers for the [`stats`](crate::servers::apis::v1::context::health_check)
//! API context.

use axum::Json;

use super::resources::{Report, Status};

/// Endpoint for container health check.
pub async fn health_check_handler() -> Json<Report> {
Json(Report { status: Status::Ok })
}
34 changes: 34 additions & 0 deletions src/servers/apis/v1/context/health_check/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//! API health check endpoint.
//!
//! It is used to check is the service is running. Especially for containers.
//!
//! # Endpoints
//!
//! - [Health Check](#health-check)
//!
//! # Health Check
//!
//! `GET /health_check`
//!
//! Returns the API status.
//!
//! **Example request**
//!
//! ```bash
//! curl "http://127.0.0.1:1212/health_check"
//! ```
//!
//! **Example response** `200`
//!
//! ```json
//! {
//! "status": "Ok",
//! }
//! ```
//!
//! **Resource**
//!
//! Refer to the API [`Stats`](crate::servers::apis::v1::context::health_check::resources::Report)
//! resource for more information about the response attributes.
pub mod handlers;
pub mod resources;
14 changes: 14 additions & 0 deletions src/servers/apis/v1/context/health_check/resources.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! API resources for the [`stats`](crate::servers::apis::v1::context::health_check)
//! API context.
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub enum Status {
Ok,
Error,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct Report {
pub status: Status,

Check warning on line 13 in src/servers/apis/v1/context/health_check/resources.rs

View check run for this annotation

Codecov / codecov/patch

src/servers/apis/v1/context/health_check/resources.rs#L13

Added line #L13 was not covered by tests
}
1 change: 1 addition & 0 deletions src/servers/apis/v1/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! Each context is a module that contains the API endpoints related to a
//! specific resource group.
pub mod auth_key;
pub mod health_check;
pub mod stats;
pub mod torrent;
pub mod whitelist;
2 changes: 1 addition & 1 deletion tests/servers/api/v1/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl Client {
}
}

async fn get(path: &str, query: Option<Query>) -> Response {
pub async fn get(path: &str, query: Option<Query>) -> Response {
match query {
Some(params) => reqwest::Client::builder()
.build()
Expand Down
20 changes: 20 additions & 0 deletions tests/servers/api/v1/contract/context/health_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use torrust_tracker::servers::apis::v1::context::health_check::resources::{Report, Status};
use torrust_tracker_test_helpers::configuration;

use crate::servers::api::test_environment::running_test_environment;
use crate::servers::api::v1::client::get;

#[tokio::test]
async fn health_check_endpoint_should_return_status_ok_if_api_is_running() {
let test_env = running_test_environment(configuration::ephemeral()).await;

let url = format!("http://{}/health_check", test_env.get_connection_info().bind_address);

let response = get(&url, None).await;

assert_eq!(response.status(), 200);
assert_eq!(response.headers().get("content-type").unwrap(), "application/json");
assert_eq!(response.json::<Report>().await.unwrap(), Report { status: Status::Ok });

test_env.stop().await;
}
1 change: 1 addition & 0 deletions tests/servers/api/v1/contract/context/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod auth_key;
pub mod health_check;
pub mod stats;
pub mod torrent;
pub mod whitelist;

0 comments on commit 48ac64f

Please sign in to comment.