Skip to content

Commit 1f32934

Browse files
abstract internal processing from handler function (#1804)
* abstract internal processing from handler function * fix clippy and deepsource issue * oss endpoint for tools * limit and timeout as integer * add tools to tool catalog * update oss tools catalog
1 parent 687f0ae commit 1f32934

17 files changed

Lines changed: 1120 additions & 193 deletions

File tree

‎src/handlers/http/alerts.rs‎

Lines changed: 97 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,18 @@ use crate::{
2222
alerts::{
2323
ALERTS, AlertError, AlertState, Severity,
2424
alert_enums::{AlertType, NotificationState},
25-
alert_structs::{AlertConfig, AlertRequest, AlertStateEntry, NotificationStateRequest},
25+
alert_structs::{
26+
AlertConfig, AlertConfigResponse, AlertRequest, AlertStateEntry,
27+
NotificationStateRequest,
28+
},
2629
alert_traits::AlertTrait,
2730
alert_types::ThresholdAlert,
2831
target::Retry,
2932
user_auth_for_alert_config,
3033
},
3134
metastore::metastore_traits::MetastoreObject,
3235
parseable::PARSEABLE,
36+
rbac::map::SessionKey,
3337
utils::{actix::extract_session_key_from_req, get_tenant_id_from_request},
3438
};
3539
use actix_web::{
@@ -211,9 +215,16 @@ pub async fn list(req: HttpRequest) -> Result<impl Responder, AlertError> {
211215
let session_key = extract_session_key_from_req(&req)?;
212216
let query_map = web::Query::<HashMap<String, String>>::from_query(req.query_string())
213217
.map_err(|_| AlertError::InvalidQueryParameter("malformed query parameters".to_string()))?;
218+
Ok(web::Json(list_internal(session_key, &query_map).await?))
219+
}
214220

221+
/// Shared alert-list implementation for HTTP handlers and in-process callers.
222+
pub async fn list_internal(
223+
session_key: SessionKey,
224+
query_map: &HashMap<String, String>,
225+
) -> Result<Vec<serde_json::Map<String, serde_json::Value>>, AlertError> {
215226
// Parse and validate query parameters
216-
let params = parse_list_query_params(&query_map)?;
227+
let params = parse_list_query_params(query_map)?;
217228

218229
// Get alerts from the manager
219230
let guard = ALERTS.read().await;
@@ -241,7 +252,7 @@ pub async fn list(req: HttpRequest) -> Result<impl Responder, AlertError> {
241252
// Paginate results
242253
let paginated_alerts = paginate_alerts(alerts_summary, params.offset, params.limit);
243254

244-
Ok(web::Json(paginated_alerts))
255+
Ok(paginated_alerts)
245256
}
246257

247258
// POST /alerts
@@ -250,6 +261,18 @@ pub async fn post(
250261
Json(alert): Json<AlertRequest>,
251262
) -> Result<impl Responder, AlertError> {
252263
let tenant_id = get_tenant_id_from_request(&req);
264+
let session_key = extract_session_key_from_req(&req)?;
265+
Ok(web::Json(
266+
post_internal(alert, &session_key, &tenant_id).await?,
267+
))
268+
}
269+
270+
/// Shared alert-creation implementation for HTTP handlers and in-process callers.
271+
pub async fn post_internal(
272+
alert: AlertRequest,
273+
session_key: &SessionKey,
274+
tenant_id: &Option<String>,
275+
) -> Result<AlertConfigResponse, AlertError> {
253276
let mut alert: AlertConfig = alert.into(tenant_id.clone()).await?;
254277

255278
if alert.notification_config.interval > alert.get_eval_frequency() {
@@ -303,22 +326,20 @@ pub async fn post(
303326

304327
// validate the incoming alert query
305328
// does the user have access to these tables or not?
306-
let session_key = extract_session_key_from_req(&req)?;
307-
308-
alert.validate(&session_key).await?;
329+
alert.validate(session_key).await?;
309330

310331
// update persistent storage first
311332
PARSEABLE
312333
.metastore
313-
.put_alert(&alert.to_alert_config(), &tenant_id)
334+
.put_alert(&alert.to_alert_config(), tenant_id)
314335
.await?;
315336

316337
// create initial alert state entry (default to NotTriggered)
317338
let state_entry =
318339
AlertStateEntry::new(*alert.get_id(), AlertState::NotTriggered, tenant_id.clone());
319340
PARSEABLE
320341
.metastore
321-
.put_alert_state(&state_entry as &dyn MetastoreObject, &tenant_id)
342+
.put_alert_state(&state_entry as &dyn MetastoreObject, tenant_id)
322343
.await?;
323344

324345
// update in memory
@@ -327,26 +348,37 @@ pub async fn post(
327348
// start the task
328349
alerts.start_task(alert.clone_box()).await?;
329350

330-
Ok(web::Json(alert.to_alert_config().to_response()))
351+
Ok(alert.to_alert_config().to_response())
331352
}
332353

333354
// GET /alerts/{alert_id}
334355
pub async fn get(req: HttpRequest, alert_id: Path<Ulid>) -> Result<impl Responder, AlertError> {
335356
let session_key = extract_session_key_from_req(&req)?;
336357
let alert_id = alert_id.into_inner();
337358
let tenant_id = get_tenant_id_from_request(&req);
359+
Ok(web::Json(
360+
get_internal(&session_key, alert_id, &tenant_id).await?,
361+
))
362+
}
363+
364+
/// Shared alert lookup implementation for HTTP handlers and in-process callers.
365+
pub async fn get_internal(
366+
session_key: &SessionKey,
367+
alert_id: Ulid,
368+
tenant_id: &Option<String>,
369+
) -> Result<AlertConfigResponse, AlertError> {
338370
let guard = ALERTS.read().await;
339371
let alerts = if let Some(alerts) = guard.as_ref() {
340372
alerts
341373
} else {
342374
return Err(AlertError::CustomError("No AlertManager set".into()));
343375
};
344376

345-
let alert = alerts.get_alert_by_id(alert_id, &tenant_id).await?;
377+
let alert = alerts.get_alert_by_id(alert_id, tenant_id).await?;
346378
// validate that the user has access to the tables mentioned in the query
347-
user_auth_for_alert_config(&session_key, &alert.to_alert_config()).await?;
379+
user_auth_for_alert_config(session_key, &alert.to_alert_config()).await?;
348380

349-
Ok(web::Json(alert.to_alert_config().to_response()))
381+
Ok(alert.to_alert_config().to_response())
350382
}
351383

352384
// DELETE /alerts/{alert_id}
@@ -457,6 +489,17 @@ pub async fn disable_alert(
457489
let session_key = extract_session_key_from_req(&req)?;
458490
let alert_id = alert_id.into_inner();
459491
let tenant_id = get_tenant_id_from_request(&req);
492+
Ok(web::Json(
493+
disable_alert_internal(&session_key, alert_id, &tenant_id).await?,
494+
))
495+
}
496+
497+
/// Shared alert-disable implementation for HTTP handlers and in-process callers.
498+
pub async fn disable_alert_internal(
499+
session_key: &SessionKey,
500+
alert_id: Ulid,
501+
tenant_id: &Option<String>,
502+
) -> Result<AlertConfigResponse, AlertError> {
460503
let guard = ALERTS.write().await;
461504
let alerts = if let Some(alerts) = guard.as_ref() {
462505
alerts
@@ -465,16 +508,16 @@ pub async fn disable_alert(
465508
};
466509

467510
// check if alert id exists in map
468-
let alert = alerts.get_alert_by_id(alert_id, &tenant_id).await?;
511+
let alert = alerts.get_alert_by_id(alert_id, tenant_id).await?;
469512
// validate that the user has access to the tables mentioned in the query
470-
user_auth_for_alert_config(&session_key, &alert.to_alert_config()).await?;
513+
user_auth_for_alert_config(session_key, &alert.to_alert_config()).await?;
471514

472515
alerts
473-
.update_state(alert_id, AlertState::Disabled, Some("".into()), &tenant_id)
516+
.update_state(alert_id, AlertState::Disabled, Some("".into()), tenant_id)
474517
.await?;
475-
let alert = alerts.get_alert_by_id(alert_id, &tenant_id).await?;
518+
let alert = alerts.get_alert_by_id(alert_id, tenant_id).await?;
476519

477-
Ok(web::Json(alert.to_alert_config().to_response()))
520+
Ok(alert.to_alert_config().to_response())
478521
}
479522

480523
// PATCH /alerts/{alert_id}/enable
@@ -487,6 +530,17 @@ pub async fn enable_alert(
487530
let session_key = extract_session_key_from_req(&req)?;
488531
let alert_id = alert_id.into_inner();
489532
let tenant_id = get_tenant_id_from_request(&req);
533+
Ok(web::Json(
534+
enable_alert_internal(&session_key, alert_id, &tenant_id).await?,
535+
))
536+
}
537+
538+
/// Shared alert-enable implementation for HTTP handlers and in-process callers.
539+
pub async fn enable_alert_internal(
540+
session_key: &SessionKey,
541+
alert_id: Ulid,
542+
tenant_id: &Option<String>,
543+
) -> Result<AlertConfigResponse, AlertError> {
490544
let guard = ALERTS.write().await;
491545
let alerts = if let Some(alerts) = guard.as_ref() {
492546
alerts
@@ -495,7 +549,7 @@ pub async fn enable_alert(
495549
};
496550

497551
// check if alert id exists in map
498-
let alert = alerts.get_alert_by_id(alert_id, &tenant_id).await?;
552+
let alert = alerts.get_alert_by_id(alert_id, tenant_id).await?;
499553

500554
// only run if alert is disabled
501555
if alert.get_state().ne(&AlertState::Disabled) {
@@ -505,19 +559,19 @@ pub async fn enable_alert(
505559
}
506560

507561
// validate that the user has access to the tables mentioned in the query
508-
user_auth_for_alert_config(&session_key, &alert.to_alert_config()).await?;
562+
user_auth_for_alert_config(session_key, &alert.to_alert_config()).await?;
509563

510564
alerts
511565
.update_state(
512566
alert_id,
513567
AlertState::NotTriggered,
514568
Some("".into()),
515-
&tenant_id,
569+
tenant_id,
516570
)
517571
.await?;
518-
let alert = alerts.get_alert_by_id(alert_id, &tenant_id).await?;
572+
let alert = alerts.get_alert_by_id(alert_id, tenant_id).await?;
519573

520-
Ok(web::Json(alert.to_alert_config().to_response()))
574+
Ok(alert.to_alert_config().to_response())
521575
}
522576

523577
// PUT /alerts/{alert_id}
@@ -616,16 +670,27 @@ pub async fn evaluate_alert(
616670
let session_key = extract_session_key_from_req(&req)?;
617671
let alert_id = alert_id.into_inner();
618672
let tenant_id = get_tenant_id_from_request(&req);
673+
Ok(Json(
674+
evaluate_alert_internal(&session_key, alert_id, &tenant_id).await?,
675+
))
676+
}
677+
678+
/// Shared alert-evaluation implementation for HTTP handlers and in-process callers.
679+
pub async fn evaluate_alert_internal(
680+
session_key: &SessionKey,
681+
alert_id: Ulid,
682+
tenant_id: &Option<String>,
683+
) -> Result<AlertConfigResponse, AlertError> {
619684
let guard = ALERTS.write().await;
620685
let alerts = if let Some(alerts) = guard.as_ref() {
621686
alerts
622687
} else {
623688
return Err(AlertError::CustomError("No AlertManager set".into()));
624689
};
625690

626-
let alert = alerts.get_alert_by_id(alert_id, &tenant_id).await?;
691+
let alert = alerts.get_alert_by_id(alert_id, tenant_id).await?;
627692

628-
user_auth_for_alert_config(&session_key, &alert.to_alert_config()).await?;
693+
user_auth_for_alert_config(session_key, &alert.to_alert_config()).await?;
629694

630695
let config = alert.to_alert_config().to_response();
631696

@@ -635,17 +700,21 @@ pub async fn evaluate_alert(
635700
// add the task back again so that it evaluates right now
636701
alerts.start_task(alert).await?;
637702

638-
Ok(Json(config))
703+
Ok(config)
639704
}
640705

641706
pub async fn list_tags(req: HttpRequest) -> Result<impl Responder, AlertError> {
707+
let tenant_id = get_tenant_id_from_request(&req);
708+
Ok(web::Json(list_tags_internal(&tenant_id).await?))
709+
}
710+
711+
/// Shared alert-tag implementation for HTTP handlers and in-process callers.
712+
pub async fn list_tags_internal(tenant_id: &Option<String>) -> Result<Vec<String>, AlertError> {
642713
let guard = ALERTS.read().await;
643714
let alerts = if let Some(alerts) = guard.as_ref() {
644715
alerts
645716
} else {
646717
return Err(AlertError::CustomError("No AlertManager set".into()));
647718
};
648-
let tenant_id = get_tenant_id_from_request(&req);
649-
let tags = alerts.list_tags(&tenant_id).await;
650-
Ok(web::Json(tags))
719+
Ok(alerts.list_tags(tenant_id).await)
651720
}

‎src/handlers/http/cluster/mod.rs‎

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,14 @@ pub async fn send_retention_cleanup_request(
939939

940940
/// Fetches cluster information for all nodes (ingestor, indexer, querier and prism)
941941
pub async fn get_cluster_info(req: HttpRequest) -> Result<impl Responder, StreamError> {
942-
let tenant_id = &get_tenant_id_from_request(&req);
942+
let tenant_id = get_tenant_id_from_request(&req);
943+
Ok(actix_web::HttpResponse::Ok().json(get_cluster_info_internal(&tenant_id).await?))
944+
}
945+
946+
/// Shared cluster-info implementation for HTTP handlers and in-process callers.
947+
pub async fn get_cluster_info_internal(
948+
tenant_id: &Option<String>,
949+
) -> Result<Vec<utils::ClusterInfo>, StreamError> {
943950
// Get querier, ingestor and indexer metadata concurrently
944951
let (prism_result, querier_result, ingestor_result, indexer_result) = future::join4(
945952
get_node_info(NodeType::Prism, tenant_id),
@@ -996,7 +1003,7 @@ pub async fn get_cluster_info(req: HttpRequest) -> Result<impl Responder, Stream
9961003
infos.extend(querier_infos?);
9971004
infos.extend(ingestor_infos?);
9981005
infos.extend(indexer_infos?);
999-
Ok(actix_web::HttpResponse::Ok().json(infos))
1006+
Ok(infos)
10001007
}
10011008

10021009
/// Fetches info for a single node
@@ -1085,13 +1092,18 @@ async fn fetch_nodes_info<T: Metadata>(
10851092
}
10861093

10871094
pub async fn get_cluster_metrics(req: HttpRequest) -> Result<impl Responder, PostError> {
1088-
let tenant_id = &get_tenant_id_from_request(&req);
1089-
let dresses = fetch_cluster_metrics(tenant_id).await.map_err(|err| {
1095+
let tenant_id = get_tenant_id_from_request(&req);
1096+
Ok(actix_web::HttpResponse::Ok().json(get_cluster_metrics_internal(&tenant_id).await?))
1097+
}
1098+
1099+
/// Shared cluster-metrics implementation for HTTP handlers and in-process callers.
1100+
pub async fn get_cluster_metrics_internal(
1101+
tenant_id: &Option<String>,
1102+
) -> Result<Vec<Metrics>, PostError> {
1103+
fetch_cluster_metrics(tenant_id).await.map_err(|err| {
10901104
error!("Fatal: failed to fetch cluster metrics: {:?}", err);
10911105
PostError::Invalid(err.into())
1092-
})?;
1093-
1094-
Ok(actix_web::HttpResponse::Ok().json(dresses))
1106+
})
10951107
}
10961108

10971109
/// get node info for a specific node type

‎src/handlers/http/health_check.rs‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ use crate::{parseable::PARSEABLE, storage::object_storage::sync_all_streams};
4141
pub static SIGNAL_RECEIVED: Lazy<Arc<Mutex<bool>>> = Lazy::new(|| Arc::new(Mutex::new(false)));
4242

4343
pub async fn liveness() -> HttpResponse {
44-
HttpResponse::new(StatusCode::OK)
44+
HttpResponse::new(liveness_internal())
45+
}
46+
47+
pub fn liveness_internal() -> StatusCode {
48+
StatusCode::OK
4549
}
4650

4751
pub async fn check_shutdown_middleware(
@@ -107,16 +111,20 @@ async fn perform_object_store_sync() {
107111

108112
pub async fn readiness(req: HttpRequest) -> HttpResponse {
109113
let tenant_id = get_tenant_id_from_request(&req);
114+
HttpResponse::new(readiness_internal(&tenant_id).await)
115+
}
116+
117+
pub async fn readiness_internal(tenant_id: &Option<String>) -> StatusCode {
110118
// Check the object store connection
111119
if PARSEABLE
112120
.storage
113121
.get_object_store()
114-
.check(&tenant_id)
122+
.check(tenant_id)
115123
.await
116124
.is_ok()
117125
{
118-
HttpResponse::new(StatusCode::OK)
126+
StatusCode::OK
119127
} else {
120-
HttpResponse::new(StatusCode::SERVICE_UNAVAILABLE)
128+
StatusCode::SERVICE_UNAVAILABLE
121129
}
122130
}

0 commit comments

Comments
 (0)