Skip to main content

nodes_registry/
module.rs

1use anyhow::Result;
2use async_trait::async_trait;
3use std::sync::{Arc, OnceLock};
4
5use modkit::Module;
6use modkit::context::ModuleCtx;
7use modkit::contracts::{OpenApiRegistry, RestApiCapability};
8
9use crate::domain::local_client::NodesRegistryLocalClient;
10use crate::domain::service::Service;
11use nodes_registry_sdk::NodesRegistryClient;
12
13#[modkit::module(
14    name = "nodes-registry",
15    capabilities = [rest],
16    client = nodes_registry_sdk::NodesRegistryClient
17)]
18pub struct NodesRegistry {
19    service: OnceLock<Arc<Service>>,
20}
21
22impl Default for NodesRegistry {
23    fn default() -> Self {
24        Self {
25            service: OnceLock::new(),
26        }
27    }
28}
29
30#[async_trait]
31impl Module for NodesRegistry {
32    async fn init(&self, ctx: &ModuleCtx) -> Result<()> {
33        // Create the service
34        let service = Arc::new(Service::new());
35        self.service
36            .set(service.clone())
37            .map_err(|_| anyhow::anyhow!("{} module already initialized", Self::MODULE_NAME))?;
38
39        // Expose the client to the ClientHub
40        let api: Arc<dyn NodesRegistryClient> = Arc::new(NodesRegistryLocalClient::new(service));
41        ctx.client_hub().register::<dyn NodesRegistryClient>(api);
42
43        Ok(())
44    }
45}
46
47impl RestApiCapability for NodesRegistry {
48    fn register_rest(
49        &self,
50        _ctx: &ModuleCtx,
51        router: axum::Router,
52        openapi: &dyn OpenApiRegistry,
53    ) -> Result<axum::Router> {
54        let service = self
55            .service
56            .get()
57            .ok_or_else(|| anyhow::anyhow!("Service not initialized"))?
58            .clone();
59
60        let router = crate::api::rest::routes::register_routes(router, openapi, service);
61
62        tracing::info!("Nodes registry REST routes registered");
63        Ok(router)
64    }
65}