|
| 1 | +//! Config snapshot endpoints. |
| 2 | +//! |
| 3 | +//! These endpoints allow retrieving config snapshots by hash, or the live config. |
| 4 | +
|
| 5 | +use std::collections::HashMap; |
| 6 | + |
| 7 | +use axum::Json; |
| 8 | +use axum::extract::{Path, State}; |
| 9 | +use serde::{Deserialize, Serialize}; |
| 10 | +use tracing::instrument; |
| 11 | + |
| 12 | +use crate::config::snapshot::{ConfigSnapshot, SnapshotHash}; |
| 13 | +use crate::config::stored::StoredConfig; |
| 14 | +use crate::db::ConfigQueries; |
| 15 | +use crate::error::{Error, ErrorDetails}; |
| 16 | +use crate::utils::gateway::{AppState, AppStateData}; |
| 17 | + |
| 18 | +/// Response containing a config snapshot. |
| 19 | +#[derive(Debug, Serialize, Deserialize)] |
| 20 | +pub struct GetConfigResponse { |
| 21 | + /// The config in a form suitable for serialization. |
| 22 | + pub config: StoredConfig, |
| 23 | + /// The hash identifying this config version. |
| 24 | + pub hash: String, |
| 25 | + /// Templates that were loaded from the filesystem. |
| 26 | + pub extra_templates: HashMap<String, String>, |
| 27 | + /// User-defined tags for categorizing or labeling this config snapshot. |
| 28 | + pub tags: HashMap<String, String>, |
| 29 | +} |
| 30 | + |
| 31 | +impl GetConfigResponse { |
| 32 | + fn from_snapshot(snapshot: ConfigSnapshot) -> Self { |
| 33 | + Self { |
| 34 | + hash: snapshot.hash.to_string(), |
| 35 | + config: snapshot.config, |
| 36 | + extra_templates: snapshot.extra_templates, |
| 37 | + tags: snapshot.tags, |
| 38 | + } |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +/// Handler for `GET /internal/config` |
| 43 | +/// |
| 44 | +/// Returns the live config snapshot. |
| 45 | +#[axum::debug_handler(state = AppStateData)] |
| 46 | +#[instrument(name = "config.get_live", skip_all)] |
| 47 | +pub async fn get_live_config_handler( |
| 48 | + State(app_state): AppState, |
| 49 | +) -> Result<Json<GetConfigResponse>, Error> { |
| 50 | + let hash = app_state.config.hash.clone(); |
| 51 | + let snapshot = app_state |
| 52 | + .clickhouse_connection_info |
| 53 | + .get_config_snapshot(hash) |
| 54 | + .await?; |
| 55 | + |
| 56 | + Ok(Json(GetConfigResponse::from_snapshot(snapshot))) |
| 57 | +} |
| 58 | + |
| 59 | +/// Handler for `GET /internal/config/{hash}` |
| 60 | +/// |
| 61 | +/// Returns a config snapshot by hash. |
| 62 | +#[axum::debug_handler(state = AppStateData)] |
| 63 | +#[instrument(name = "config.get_by_hash", skip_all, fields(hash = %hash))] |
| 64 | +pub async fn get_config_by_hash_handler( |
| 65 | + State(app_state): AppState, |
| 66 | + Path(hash): Path<String>, |
| 67 | +) -> Result<Json<GetConfigResponse>, Error> { |
| 68 | + let snapshot_hash: SnapshotHash = hash.parse().map_err(|_| { |
| 69 | + Error::new(ErrorDetails::ConfigSnapshotNotFound { |
| 70 | + snapshot_hash: hash.clone(), |
| 71 | + }) |
| 72 | + })?; |
| 73 | + |
| 74 | + let snapshot = app_state |
| 75 | + .clickhouse_connection_info |
| 76 | + .get_config_snapshot(snapshot_hash) |
| 77 | + .await?; |
| 78 | + |
| 79 | + Ok(Json(GetConfigResponse::from_snapshot(snapshot))) |
| 80 | +} |
0 commit comments