use crate::control::Hydrant; use axum::{ Json, Router, extract::State, http::StatusCode, routing::{get, patch}, }; use serde::{Deserialize, Serialize}; pub fn router() -> Router { Router::new() .route("/ingestion", get(get_ingestion)) .route("/ingestion", patch(patch_ingestion)) } #[derive(Serialize)] pub struct IngestionStatus { #[cfg(feature = "indexer")] pub crawler: bool, pub firehose: bool, #[cfg(feature = "indexer")] pub backfill: bool, } pub async fn get_ingestion(State(hydrant): State) -> Json { Json(IngestionStatus { #[cfg(feature = "indexer")] crawler: hydrant.crawler.is_enabled(), firehose: hydrant.firehose.is_enabled(), #[cfg(feature = "indexer")] backfill: hydrant.backfill.is_enabled(), }) } #[derive(Deserialize)] pub struct IngestionPatch { #[cfg(feature = "indexer")] #[serde(default)] pub crawler: Option, #[serde(default)] pub firehose: Option, #[cfg(feature = "indexer")] #[serde(default)] pub backfill: Option, } pub async fn patch_ingestion( State(hydrant): State, Json(body): Json, ) -> StatusCode { #[cfg(feature = "indexer")] if let Some(crawler) = body.crawler { if crawler { hydrant.crawler.enable(); } else { hydrant.crawler.disable(); } } if let Some(firehose) = body.firehose { if firehose { hydrant.firehose.enable(); } else { hydrant.firehose.disable(); } } #[cfg(feature = "indexer")] if let Some(backfill) = body.backfill { if backfill { hydrant.backfill.enable(); } else { hydrant.backfill.disable(); } } StatusCode::OK } #[cfg(test)] mod tests { use super::*; #[test] fn ingestion_json_contracts_follow_compiled_mode() { let patch: IngestionPatch = serde_json::from_str(r#"{"firehose":false}"#).unwrap(); assert_eq!(patch.firehose, Some(false)); #[cfg(feature = "indexer")] { assert_eq!(patch.crawler, None); assert_eq!(patch.backfill, None); } let status = IngestionStatus { #[cfg(feature = "indexer")] crawler: true, firehose: false, #[cfg(feature = "indexer")] backfill: true, }; let encoded = serde_json::to_value(status).unwrap(); assert_eq!(encoded["firehose"], false); #[cfg(feature = "indexer")] { assert_eq!(encoded["crawler"], true); assert_eq!(encoded["backfill"], true); } #[cfg(not(feature = "indexer"))] { assert!(encoded.get("crawler").is_none()); assert!(encoded.get("backfill").is_none()); } assert!(serde_json::from_str::(r#"{"firehose":"false"}"#).is_err()); } }