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