use std::sync::Arc; use axum::{ Json, extract::{Path, State}, http::StatusCode, response::IntoResponse, }; use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::routes::api::{ApiRouter, AppError}; use crate::service::proxy::log_setting::{ CreateLogSettingParams, LogSettingService, UpdateLogSettingParams, }; use crate::service::proxy::types::LogSettingConfig; #[derive(Serialize)] pub(crate) struct LogSettingResponse { pub id: Uuid, pub access_log_path: Option, pub error_log_path: Option, pub log_level: Option, pub override_of_id: Option, } impl From for LogSettingResponse { fn from(c: LogSettingConfig) -> Self { Self { id: c.id, access_log_path: c.access_log_path, error_log_path: c.error_log_path, log_level: c.log_level, override_of_id: c.override_of_id, } } } #[derive(Deserialize)] pub(crate) struct CreateLogSettingRequest { pub access_log_path: Option, pub error_log_path: Option, pub log_level: Option, pub override_of_id: Option, } impl From for CreateLogSettingParams { fn from(r: CreateLogSettingRequest) -> Self { Self { server_id: Uuid::nil(), access_log_path: r.access_log_path, error_log_path: r.error_log_path, log_level: r.log_level, override_of_id: r.override_of_id, } } } #[derive(Deserialize)] pub(crate) struct UpdateLogSettingRequest { pub server_id: Option, pub access_log_path: Option>, pub error_log_path: Option>, pub log_level: Option>, pub override_of_id: Option>, } impl From for UpdateLogSettingParams { fn from(r: UpdateLogSettingRequest) -> Self { Self { server_id: r.server_id, access_log_path: r.access_log_path, error_log_path: r.error_log_path, log_level: r.log_level, override_of_id: r.override_of_id, } } } async fn list_log_settings( State(svc): State>, Path(server_id): Path, ) -> Result>, AppError> { let settings = svc.list_by_server(server_id).await?; Ok(Json(settings.into_iter().map(Into::into).collect())) } async fn create_log_setting( State(svc): State>, Path(server_id): Path, Json(body): Json, ) -> Result { let mut params = CreateLogSettingParams::from(body); params.server_id = server_id; let setting = svc.create(params).await?; Ok((StatusCode::CREATED, Json(LogSettingResponse::from(setting)))) } async fn get_log_setting( State(svc): State>, Path(id): Path, ) -> Result, AppError> { let setting = svc.get(id).await?; Ok(Json(setting.into())) } async fn update_log_setting( State(svc): State>, Path(id): Path, Json(body): Json, ) -> Result, AppError> { let setting = svc.update(id, body.into()).await?; Ok(Json(setting.into())) } async fn delete_log_setting( State(svc): State>, Path(id): Path, ) -> Result { let deleted = svc.delete(id).await?; if deleted { Ok((StatusCode::NO_CONTENT,)) } else { Err(AppError::NotFound) } } pub(super) fn routes() -> ApiRouter { ApiRouter::new() .route( "/server-blocks/{server_id}/log-settings", axum::routing::get(list_log_settings).post(create_log_setting), ) .route( "/log-settings/{id}", axum::routing::get(get_log_setting) .put(update_log_setting) .delete(delete_log_setting), ) }