scouter_server/api/
handler.rs1use crate::api::schema::{DriftRecordRequest, ServiceDriftRequest};
2use crate::sql::postgres::TimeInterval;
3use crate::sql::schema::{DriftRecord, MonitorProfile};
4use axum::{
5 extract::{Query, State},
6 http::StatusCode,
7 response::IntoResponse,
8 Json,
9};
10use serde_json::json;
11use std::sync::Arc;
12use tracing::{error, info};
13
14use crate::api::route::AppState;
15
16pub async fn health_check() -> impl IntoResponse {
17 info!("Health check endpoint is called");
18
19 const MESSAGE: &str = "Alive";
20
21 let json_response = serde_json::json!({
22 "status": "success",
23 "message": MESSAGE
24 });
25
26 Json(json_response)
27}
28
29pub async fn get_drift(
30 State(data): State<Arc<AppState>>,
31 params: Query<ServiceDriftRequest>,
32) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
33 let time_interval = TimeInterval::from_string(¶ms.time_window).to_minutes();
36
37 let query_result = &data
38 .db
39 .get_binned_drift_records(
40 ¶ms.name,
41 ¶ms.repository,
42 ¶ms.version,
43 ¶ms.max_data_points,
44 &time_interval,
45 )
46 .await;
47
48 match query_result {
49 Ok(result) => {
50 let json_response = serde_json::json!({
51 "status": "success",
52 "data": result
53 });
54 Ok(Json(json_response))
55 }
56 Err(e) => {
57 error!("Failed to query drift records: {:?}", e);
58 let json_response = json!({
59 "status": "error",
60 "message": format!("{:?}", e)
61 });
62 Err((StatusCode::INTERNAL_SERVER_ERROR, Json(json_response)))
63 }
64 }
65}
66
67pub async fn insert_drift(
68 State(data): State<Arc<AppState>>,
69 Json(body): Json<DriftRecordRequest>,
70) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
71 let record = DriftRecord {
73 created_at: body
74 .created_at
75 .unwrap_or_else(|| chrono::Utc::now().naive_utc()),
76 name: body.name.clone(),
77 repository: body.repository.clone(),
78 feature: body.feature.clone(),
79 value: body.value,
80 version: body.version.clone(),
81 };
82
83 let query_result = &data.db.insert_drift_record(&record).await;
84
85 match query_result {
86 Ok(_) => {
87 let json_response = json!({
88 "status": "success",
89 "message": "Record inserted successfully"
90 });
91 Ok(Json(json_response))
92 }
93 Err(e) => {
94 error!("Failed to insert drift record: {:?}", e);
95 let json_response = json!({
96 "status": "error",
97 "message": format!("{:?}", e)
98 });
99 Err((StatusCode::INTERNAL_SERVER_ERROR, Json(json_response)))
100 }
101 }
102}
103
104pub async fn insert_drift_profile(
105 State(data): State<Arc<AppState>>,
106 Json(body): Json<MonitorProfile>,
107) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
108 let query_result = &data.db.insert_drift_profile(&body).await;
109
110 match query_result {
111 Ok(_) => {
112 let json_response = json!({
113 "status": "success",
114 "message": "Monitor profile inserted successfully"
115 });
116 Ok(Json(json_response))
117 }
118 Err(e) => {
119 error!("Failed to insert monitor profile: {:?}", e);
120 let json_response = json!({
121 "status": "error",
122 "message": format!("{:?}", e)
123 });
124 Err((StatusCode::INTERNAL_SERVER_ERROR, Json(json_response)))
125 }
126 }
127}