Skip to main content

mockforge_ui/
lib.rs

1//! Pillars: [DevX]
2//!
3//! # MockForge UI
4//!
5//! Web-based admin interface for managing mock servers.
6
7pub mod audit;
8pub mod auth;
9pub mod handlers;
10pub mod rbac;
11pub mod routes;
12// Templates module removed; static assets in `static/` are the single source of truth
13pub mod models;
14pub mod prometheus_client;
15pub mod time_travel_handlers;
16
17pub use models::{RequestLog, RouteInfo, ServerStatus, SystemInfo};
18pub use routes::create_admin_router;
19
20use std::net::SocketAddr;
21
22/// Start the admin UI server
23///
24/// # Arguments
25/// * `addr` - Address to bind the admin server to
26/// * `http_server_addr` - HTTP server address
27/// * `ws_server_addr` - WebSocket server address
28/// * `grpc_server_addr` - gRPC server address
29/// * `graphql_server_addr` - GraphQL server address
30/// * `api_enabled` - Whether API endpoints are enabled
31/// * `prometheus_url` - Prometheus metrics URL
32/// * `chaos_api_state` - Optional chaos API state for hot-reload support
33/// * `latency_injector` - Optional latency injector for hot-reload support
34/// * `mockai` - Optional MockAI instance for hot-reload support
35/// * `continuum_config` - Optional Reality Continuum configuration
36/// * `virtual_clock` - Optional virtual clock for time-based progression
37/// * `recorder` - Optional traffic recorder
38/// * `federation` - Optional federation instance
39/// * `vbr_engine` - Optional VBR engine
40#[allow(clippy::too_many_arguments)]
41pub async fn start_admin_server(
42    addr: SocketAddr,
43    http_server_addr: Option<SocketAddr>,
44    ws_server_addr: Option<SocketAddr>,
45    grpc_server_addr: Option<SocketAddr>,
46    graphql_server_addr: Option<SocketAddr>,
47    api_enabled: bool,
48    prometheus_url: String,
49    chaos_api_state: Option<std::sync::Arc<mockforge_chaos::api::ChaosApiState>>,
50    latency_injector: Option<
51        std::sync::Arc<tokio::sync::RwLock<mockforge_core::latency::LatencyInjector>>,
52    >,
53    mockai: Option<
54        std::sync::Arc<tokio::sync::RwLock<mockforge_core::intelligent_behavior::MockAI>>,
55    >,
56    continuum_config: Option<mockforge_core::ContinuumConfig>,
57    virtual_clock: Option<std::sync::Arc<mockforge_core::VirtualClock>>,
58    recorder: Option<std::sync::Arc<mockforge_recorder::Recorder>>,
59    federation: Option<std::sync::Arc<mockforge_federation::Federation>>,
60    vbr_engine: Option<std::sync::Arc<mockforge_vbr::VbrEngine>>,
61) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
62    let app = create_admin_router(
63        http_server_addr,
64        ws_server_addr,
65        grpc_server_addr,
66        graphql_server_addr,
67        api_enabled,
68        addr.port(),
69        prometheus_url,
70        chaos_api_state,
71        latency_injector,
72        mockai,
73        continuum_config,
74        virtual_clock,
75        recorder,
76        federation,
77        vbr_engine,
78    );
79
80    tracing::info!("Starting MockForge Admin UI on {}", addr);
81
82    let listener = tokio::net::TcpListener::bind(addr).await.map_err(|e| {
83        format!(
84            "Failed to bind Admin UI server to port {}: {}\n\
85             Hint: The port may already be in use. Try using a different port with --admin-port or check if another process is using this port with: lsof -i :{} or netstat -tulpn | grep {}",
86            addr.port(), e, addr.port(), addr.port()
87        )
88    })?;
89
90    axum::serve(listener, app).await?;
91
92    Ok(())
93}
94
95// Generated by build.rs — embeds real UI assets when available, placeholders otherwise.
96include!(concat!(env!("OUT_DIR"), "/ui_content.rs"));
97
98#[cfg(test)]
99mod tests {
100    use super::*;
101
102    #[test]
103    fn test_get_admin_html() {
104        let html = get_admin_html();
105        assert!(!html.is_empty());
106        assert!(html.contains("<!DOCTYPE html>") || html.contains("<html"));
107    }
108
109    #[test]
110    fn test_get_admin_css() {
111        let _css = get_admin_css();
112        // Content may be a placeholder when UI is not built
113    }
114
115    #[test]
116    fn test_get_admin_js() {
117        let _js = get_admin_js();
118        // Content may be a placeholder when UI is not built
119    }
120}