1use async_trait::async_trait;
4use http::StatusCode;
5use saluki_api::{
6 extract::State,
7 response::IntoResponse,
8 routing::{get, Router},
9 APIHandler, DynamicRoute, EndpointType,
10};
11use saluki_common::sync::shutdown::ShutdownHandle;
12use saluki_config::GenericConfiguration;
13use saluki_core::runtime::{state::DataspaceRegistry, InitializationError, Supervisable, SupervisorFuture};
14use saluki_error::generic_error;
15use serde_json::Value;
16
17#[derive(Clone)]
19pub struct ConfigState {
20 config: GenericConfiguration,
21}
22
23pub struct ConfigAPIHandler {
29 state: ConfigState,
30}
31
32impl ConfigAPIHandler {
33 fn new(config: GenericConfiguration) -> Self {
34 Self {
35 state: ConfigState { config },
36 }
37 }
38
39 async fn config_handler(State(state): State<ConfigState>) -> impl IntoResponse {
40 match state.config.as_typed::<Value>() {
41 Ok(config) => (StatusCode::OK, serde_json::to_string(&config).unwrap()).into_response(),
42 Err(e) => (
43 StatusCode::INTERNAL_SERVER_ERROR,
44 format!("Failed to get configuration: {}", e),
45 )
46 .into_response(),
47 }
48 }
49}
50
51impl APIHandler for ConfigAPIHandler {
52 type State = ConfigState;
53
54 fn generate_initial_state(&self) -> Self::State {
55 self.state.clone()
56 }
57
58 fn generate_routes(&self) -> Router<Self::State> {
59 Router::new().route("/config", get(Self::config_handler))
60 }
61}
62
63pub struct ConfigWorker {
69 handler: ConfigAPIHandler,
70}
71
72impl ConfigWorker {
73 pub fn new(config: GenericConfiguration) -> Self {
75 Self {
76 handler: ConfigAPIHandler::new(config),
77 }
78 }
79}
80
81#[async_trait]
82impl Supervisable for ConfigWorker {
83 fn name(&self) -> &str {
84 "config-api"
85 }
86
87 async fn initialize(&self, process_shutdown: ShutdownHandle) -> Result<SupervisorFuture, InitializationError> {
88 let config_route = DynamicRoute::http(EndpointType::Privileged, &self.handler);
89
90 Ok(Box::pin(async move {
91 DataspaceRegistry::try_current()
92 .ok_or_else(|| generic_error!("Dataspace not available."))?
93 .assert(config_route, "config-api");
94
95 process_shutdown.await;
96 Ok(())
97 }))
98 }
99}