Skip to main content

camel_core/lifecycle/adapters/
runtime_execution.rs

1use async_trait::async_trait;
2
3use camel_api::{CamelError, HealthStatus};
4
5use crate::lifecycle::adapters::controller_actor::RouteControllerHandle;
6use crate::lifecycle::application::RouteDefinition;
7use crate::lifecycle::application::ports::{InFlightCountResult, RuntimeExecutionPort};
8use crate::lifecycle::domain::DomainError;
9/// Runtime side-effect adapter backed by the technical route controller.
10#[derive(Clone)]
11pub struct RuntimeExecutionAdapter {
12    controller: RouteControllerHandle,
13}
14
15impl RuntimeExecutionAdapter {
16    pub fn new(controller: RouteControllerHandle) -> Self {
17        Self { controller }
18    }
19}
20
21fn to_domain(e: CamelError) -> DomainError {
22    DomainError::InvalidState(e.to_string())
23}
24
25#[async_trait]
26impl RuntimeExecutionPort for RuntimeExecutionAdapter {
27    async fn register_route(&self, definition: RouteDefinition) -> Result<(), DomainError> {
28        self.controller
29            .add_route(definition)
30            .await
31            .map_err(to_domain)
32    }
33
34    async fn start_route(&self, route_id: &str) -> Result<(), DomainError> {
35        self.controller
36            .start_route(route_id)
37            .await
38            .map_err(to_domain)
39    }
40
41    async fn stop_route(
42        &self,
43        route_id: &str,
44        stop_budget: Option<std::time::Duration>,
45    ) -> Result<(), DomainError> {
46        self.controller
47            .stop_route_with_budget(route_id, stop_budget)
48            .await
49            .map_err(to_domain)
50    }
51
52    async fn suspend_route(&self, route_id: &str) -> Result<(), DomainError> {
53        self.controller
54            .suspend_route(route_id)
55            .await
56            .map_err(to_domain)
57    }
58
59    async fn resume_route(&self, route_id: &str) -> Result<(), DomainError> {
60        self.controller
61            .resume_route(route_id)
62            .await
63            .map_err(to_domain)
64    }
65
66    async fn reload_route(&self, route_id: &str) -> Result<(), DomainError> {
67        self.controller
68            .restart_route(route_id)
69            .await
70            .map_err(to_domain)
71    }
72
73    async fn remove_route(&self, route_id: &str) -> Result<(), DomainError> {
74        self.controller
75            .remove_route(route_id)
76            .await
77            .map_err(to_domain)
78    }
79
80    async fn in_flight_count(&self, route_id: &str) -> Result<InFlightCountResult, DomainError> {
81        Ok(
82            match self
83                .controller
84                .in_flight_count(route_id)
85                .await
86                .map_err(to_domain)?
87            {
88                Some(count) => InFlightCountResult::InFlightCount {
89                    route_id: route_id.to_string(),
90                    count,
91                },
92                None => InFlightCountResult::RouteNotFound {
93                    route_id: route_id.to_string(),
94                },
95            },
96        )
97    }
98
99    async fn list_endpoints(&self) -> Result<Vec<String>, DomainError> {
100        self.controller.list_endpoints().await.map_err(to_domain)
101    }
102
103    async fn routes_for_endpoint(&self, uri: &str) -> Result<Vec<String>, DomainError> {
104        self.controller
105            .routes_for_endpoint(uri)
106            .await
107            .map_err(to_domain)
108    }
109
110    async fn health_check_endpoint(&self, uri: &str) -> Result<HealthStatus, DomainError> {
111        self.controller
112            .health_check_endpoint(uri)
113            .await
114            .map_err(to_domain)
115    }
116}