Skip to main content

camel_component_api/
component_context.rs

1use std::sync::Arc;
2
3use camel_api::{AsyncHealthCheck, MetricsCollector, PlatformService};
4use camel_language_api::Language;
5
6use crate::Component;
7
8/// Runtime context passed to components during endpoint creation.
9pub trait ComponentContext: Send + Sync {
10    /// Resolve a component by scheme.
11    fn resolve_component(&self, scheme: &str) -> Option<Arc<dyn Component>>;
12
13    /// Resolve a language by name.
14    fn resolve_language(&self, name: &str) -> Option<Arc<dyn Language>>;
15
16    /// Access the active metrics collector.
17    fn metrics(&self) -> Arc<dyn MetricsCollector>;
18
19    /// Access the active health-check registry.
20    ///
21    /// Used by component code paths that need to pin a route Unhealthy
22    /// (category (g) per ADR-0012). Default: NoOp — tests/examples inherit
23    /// the no-op. Concrete runtimes (CamelContext) override to return the
24    /// real registry.
25    fn health(&self) -> Arc<dyn crate::HealthCheckRegistry> {
26        Arc::new(crate::NoOpHealthCheckRegistry)
27    }
28
29    /// Access the active platform service.
30    fn platform_service(&self) -> Arc<dyn PlatformService>;
31
32    fn register_route_health_check(&self, route_id: &str, check: Arc<dyn AsyncHealthCheck>);
33
34    fn unregister_route_health_check(&self, route_id: &str);
35
36    fn route_id(&self) -> Option<&str> {
37        None
38    }
39
40    fn register_current_route_health_check(&self, check: Arc<dyn AsyncHealthCheck>) {
41        if let Some(id) = self.route_id() {
42            self.register_route_health_check(id, check);
43        }
44    }
45}
46
47/// Default no-op component context for tests/examples.
48pub struct NoOpComponentContext;
49
50impl ComponentContext for NoOpComponentContext {
51    fn resolve_component(&self, _scheme: &str) -> Option<Arc<dyn Component>> {
52        None
53    }
54
55    fn resolve_language(&self, _name: &str) -> Option<Arc<dyn Language>> {
56        None
57    }
58
59    fn metrics(&self) -> Arc<dyn MetricsCollector> {
60        Arc::new(camel_api::NoOpMetrics)
61    }
62
63    fn platform_service(&self) -> Arc<dyn PlatformService> {
64        Arc::new(camel_api::NoopPlatformService::default())
65    }
66
67    fn register_route_health_check(&self, _route_id: &str, _check: Arc<dyn AsyncHealthCheck>) {}
68
69    fn unregister_route_health_check(&self, _route_id: &str) {}
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn component_context_health_default_is_noop() {
78        let ctx = NoOpComponentContext;
79        let h = ctx.health();
80        // Must not panic.
81        h.force_unhealthy_for_route("any", "any", "any");
82    }
83}