1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::sync::Arc;
use camel_api::{AsyncHealthCheck, MetricsCollector, PlatformService};
use camel_language_api::Language;
use crate::Component;
/// Runtime context passed to components during endpoint creation.
pub trait ComponentContext: Send + Sync {
/// Resolve a component by scheme.
fn resolve_component(&self, scheme: &str) -> Option<Arc<dyn Component>>;
/// Resolve a language by name.
fn resolve_language(&self, name: &str) -> Option<Arc<dyn Language>>;
/// Access the active metrics collector.
fn metrics(&self) -> Arc<dyn MetricsCollector>;
/// Context-global counter of accepted-not-completed exchanges
/// (drainclaim). Production contexts return the counter installed on
/// every `ConsumerContext` at consumer start and read by
/// `CamelContext::total_in_flight()` for the drain verdict. Default
/// `None` keeps test contexts uncounted.
fn in_flight_counter(&self) -> Option<std::sync::Arc<std::sync::atomic::AtomicU64>> {
None
}
/// Snapshot of the `[observability.metrics].components` lever —
/// gates only the uniform component-operations family served through
/// `RuntimeObservability::component_metrics()`; error-family
/// emission is never lever-gated. Default false (opt-in);
/// `CamelContext` overrides this with its `MetricsLeversConfig`
/// snapshot.
fn component_metrics_enabled(&self) -> bool {
false
}
/// Access the active health-check registry.
///
/// Used by component code paths that need to pin a route Unhealthy
/// (category (g) per ADR-0012). Default: NoOp — tests/examples inherit
/// the no-op. Concrete runtimes (CamelContext) override to return the
/// real registry.
fn health(&self) -> Arc<dyn crate::HealthCheckRegistry> {
Arc::new(crate::NoOpHealthCheckRegistry)
}
/// Access the active platform service.
fn platform_service(&self) -> Arc<dyn PlatformService>;
fn register_route_health_check(&self, route_id: &str, check: Arc<dyn AsyncHealthCheck>);
fn unregister_route_health_check(&self, route_id: &str);
fn route_id(&self) -> Option<&str> {
None
}
fn register_current_route_health_check(&self, check: Arc<dyn AsyncHealthCheck>) {
if let Some(id) = self.route_id() {
self.register_route_health_check(id, check);
}
}
}
/// Default no-op component context for tests/examples.
pub struct NoOpComponentContext;
impl ComponentContext for NoOpComponentContext {
fn resolve_component(&self, _scheme: &str) -> Option<Arc<dyn Component>> {
None
}
fn resolve_language(&self, _name: &str) -> Option<Arc<dyn Language>> {
None
}
fn metrics(&self) -> Arc<dyn MetricsCollector> {
Arc::new(camel_api::NoOpMetrics)
}
fn platform_service(&self) -> Arc<dyn PlatformService> {
Arc::new(camel_api::NoopPlatformService::default())
}
fn register_route_health_check(&self, _route_id: &str, _check: Arc<dyn AsyncHealthCheck>) {}
fn unregister_route_health_check(&self, _route_id: &str) {}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn component_context_health_default_is_noop() {
let ctx = NoOpComponentContext;
let h = ctx.health();
// Must not panic.
h.force_unhealthy_for_route("any", "any", "any");
}
}