Webapp
This commit is contained in:
+66
@@ -0,0 +1,66 @@
|
||||
use crate::engine::{EngineHandle, EngineMessage, EngineQuery, EngineResponse};
|
||||
use crate::dto::{LogsParams, TimelineParams};
|
||||
use axum::extract::{Query, State};
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::{IntoResponse, Json};
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use tokio::sync::oneshot;
|
||||
use tower_http::services::{ServeDir, ServeFile};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ApiState {
|
||||
engine: EngineHandle,
|
||||
}
|
||||
|
||||
pub fn router(engine: EngineHandle, static_dir: &str) -> Router {
|
||||
let state = ApiState { engine };
|
||||
let index_html = format!("{static_dir}/index.html");
|
||||
let static_service = ServeDir::new(static_dir).fallback(ServeFile::new(index_html));
|
||||
|
||||
Router::new()
|
||||
.route("/api/logs", get(get_logs))
|
||||
.route("/api/timeline", get(get_timeline))
|
||||
.route("/api/stats", get(get_stats))
|
||||
.with_state(state)
|
||||
.fallback_service(static_service)
|
||||
}
|
||||
|
||||
async fn ask(engine: &EngineHandle, query: EngineQuery) -> Result<EngineResponse, StatusCode> {
|
||||
let (respond_to, response) = oneshot::channel();
|
||||
engine
|
||||
.send(EngineMessage::Query { query, respond_to })
|
||||
.await
|
||||
.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;
|
||||
response.await.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)
|
||||
}
|
||||
|
||||
async fn get_logs(
|
||||
State(state): State<ApiState>,
|
||||
Query(params): Query<LogsParams>,
|
||||
) -> impl IntoResponse {
|
||||
match ask(&state.engine, EngineQuery::Logs(params)).await {
|
||||
Ok(EngineResponse::Logs(entries)) => Json(entries).into_response(),
|
||||
Ok(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
||||
Err(status) => status.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_timeline(
|
||||
State(state): State<ApiState>,
|
||||
Query(params): Query<TimelineParams>,
|
||||
) -> impl IntoResponse {
|
||||
match ask(&state.engine, EngineQuery::Timeline(params)).await {
|
||||
Ok(EngineResponse::Timeline(buckets)) => Json(buckets).into_response(),
|
||||
Ok(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
||||
Err(status) => status.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_stats(State(state): State<ApiState>) -> impl IntoResponse {
|
||||
match ask(&state.engine, EngineQuery::Stats).await {
|
||||
Ok(EngineResponse::Stats(stats)) => Json(stats).into_response(),
|
||||
Ok(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
||||
Err(status) => status.into_response(),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user