use std::net::SocketAddr;
use std::sync::Arc;
use axum::Router;
use axum::routing::{get, post};
use super::config::LogServerConfig;
use super::handlers::{
AppState, handle_append, handle_count, handle_healthy, handle_list_keys, handle_list_segments,
handle_metrics, handle_ready, handle_scan,
};
use super::metrics::Metrics;
use super::middleware::{MetricsLayer, TracingLayer};
use crate::LogDb;
pub struct LogServer {
log: Arc<LogDb>,
config: LogServerConfig,
}
impl LogServer {
pub fn new(log: Arc<LogDb>, config: LogServerConfig) -> Self {
Self { log, config }
}
pub async fn run(self) {
let metrics = Arc::new(Metrics::new());
let state = AppState {
log: self.log,
metrics: metrics.clone(),
};
let app = Router::new()
.route("/api/v1/log/append", post(handle_append))
.route("/api/v1/log/scan", get(handle_scan))
.route("/api/v1/log/keys", get(handle_list_keys))
.route("/api/v1/log/segments", get(handle_list_segments))
.route("/api/v1/log/count", get(handle_count))
.route("/metrics", get(handle_metrics))
.route("/-/healthy", get(handle_healthy))
.route("/-/ready", get(handle_ready))
.layer(TracingLayer::new())
.layer(MetricsLayer::new(metrics))
.with_state(state);
let addr = SocketAddr::from(([0, 0, 0, 0], self.config.port));
tracing::info!("Starting Log HTTP server on {}", addr);
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
}