o_sfu/runtime/http_server/operator/
diagnostics.rs1use std::sync::Arc;
4
5use axum::{
6 extract::{FromRef, Path, State},
7 http::StatusCode,
8 response::{IntoResponse, Response},
9};
10
11use crate::runtime::{MediaTransport, RuntimeState, diagnostics, room::RoomManager};
12
13#[derive(Debug, Clone)]
14pub(super) struct DiagnosticsServices {
15 room_manager: Arc<RoomManager>,
16 media_transport: MediaTransport,
17}
18
19impl FromRef<RuntimeState> for DiagnosticsServices {
20 fn from_ref(state: &RuntimeState) -> Self {
21 Self {
22 room_manager: Arc::clone(&state.room_manager),
23 media_transport: state.media_transport.clone(),
24 }
25 }
26}
27
28pub(super) async fn summary(State(services): State<DiagnosticsServices>) -> Response {
30 axum::Json(
31 diagnostics::summary_response(&services.room_manager, &services.media_transport).await,
32 )
33 .into_response()
34}
35
36pub(super) async fn rooms(State(services): State<DiagnosticsServices>) -> Response {
38 axum::Json(diagnostics::rooms_response(&services.room_manager, &services.media_transport).await)
39 .into_response()
40}
41
42pub(super) async fn workers(State(services): State<DiagnosticsServices>) -> Response {
44 axum::Json(
45 diagnostics::workers_response(&services.room_manager, &services.media_transport).await,
46 )
47 .into_response()
48}
49
50pub(super) async fn room_detail(
55 State(services): State<DiagnosticsServices>,
56 Path(room_id): Path<String>,
57) -> Response {
58 let payload = diagnostics::room_detail_response(
59 &services.room_manager,
60 &services.media_transport,
61 &room_id,
62 )
63 .await;
64 payload.map_or_else(
65 |_error| StatusCode::SERVICE_UNAVAILABLE.into_response(),
66 optional_response,
67 )
68}
69
70pub(super) async fn room_users(
72 State(services): State<DiagnosticsServices>,
73 Path(room_id): Path<String>,
74) -> Response {
75 let payload = diagnostics::room_users_response(
76 &services.room_manager,
77 &services.media_transport,
78 &room_id,
79 )
80 .await;
81 optional_response(payload)
82}
83
84pub(super) async fn user_detail(
86 State(services): State<DiagnosticsServices>,
87 Path((room_id, user_key)): Path<(String, String)>,
88) -> Response {
89 optional_response(
90 diagnostics::user_detail_response(
91 &services.room_manager,
92 &services.media_transport,
93 &room_id,
94 &user_key,
95 )
96 .await,
97 )
98}
99
100fn optional_response<T>(payload: Option<T>) -> Response
101where
102 axum::Json<T>: IntoResponse,
103{
104 payload.map_or_else(
105 || StatusCode::NOT_FOUND.into_response(),
106 |payload| axum::Json(payload).into_response(),
107 )
108}