camel_component_api/
endpoint.rs1use std::sync::Arc;
2use std::time::Duration;
3
4use async_trait::async_trait;
5use camel_api::{BodyType, BoxProcessor, CamelError, Exchange};
6
7use crate::ProducerContext;
8use crate::consumer::Consumer;
9use crate::runtime_observability::RuntimeObservability;
10
11#[async_trait]
19pub trait PollingConsumer: Send + Sync {
20 async fn receive(&mut self, timeout: Duration) -> Result<Option<Exchange>, CamelError>;
24}
25
26pub trait Endpoint: Send + Sync {
28 fn uri(&self) -> &str;
30
31 fn create_consumer(
38 &self,
39 rt: Arc<dyn RuntimeObservability>,
40 ) -> Result<Box<dyn Consumer>, CamelError>;
41
42 fn create_producer(
49 &self,
50 rt: Arc<dyn RuntimeObservability>,
51 ctx: &ProducerContext,
52 ) -> Result<BoxProcessor, CamelError>;
53
54 fn body_contract(&self) -> Option<BodyType> {
59 None
60 }
61
62 fn polling_consumer(&self) -> Option<Box<dyn PollingConsumer>> {
69 None
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::ComponentContext;
77 use crate::test_support::PanicRuntimeObservability;
78
79 struct MockEndpoint {
81 uri: String,
82 }
83
84 impl MockEndpoint {
85 fn new(uri: &str) -> Self {
86 Self {
87 uri: uri.to_string(),
88 }
89 }
90 }
91
92 impl Endpoint for MockEndpoint {
93 fn uri(&self) -> &str {
94 &self.uri
95 }
96
97 fn create_consumer(
98 &self,
99 _rt: Arc<dyn crate::RuntimeObservability>,
100 ) -> Result<Box<dyn Consumer>, CamelError> {
101 Err(CamelError::EndpointCreationFailed("mock".into()))
102 }
103
104 fn create_producer(
105 &self,
106 _rt: Arc<dyn crate::RuntimeObservability>,
107 _ctx: &ProducerContext,
108 ) -> Result<BoxProcessor, CamelError> {
109 Err(CamelError::ProcessorError("mock".into()))
110 }
111 }
112
113 #[test]
114 fn mock_endpoint_polling_consumer_returns_none() {
115 let ep = MockEndpoint::new("mock://test");
116 assert!(ep.polling_consumer().is_none());
117 }
118
119 #[test]
120 fn mock_endpoint_body_contract_default_is_none() {
121 let ep = MockEndpoint::new("mock://test");
122 assert!(ep.body_contract().is_none());
123 }
124
125 #[test]
126 fn mock_endpoint_uri() {
127 let ep = MockEndpoint::new("mock://test");
128 assert_eq!(ep.uri(), "mock://test");
129 }
130
131 #[test]
132 fn mock_endpoint_create_consumer_errors() {
133 let ep = MockEndpoint::new("mock://test");
134 let rt: Arc<dyn crate::RuntimeObservability> = Arc::new(PanicRuntimeObservability);
135 let result = ep.create_consumer(rt);
136 assert!(result.is_err());
137 }
138
139 #[test]
140 fn mock_endpoint_create_producer_errors() {
141 let ep = MockEndpoint::new("mock://test");
142 let ctx = ProducerContext::new();
143 let rt: Arc<dyn crate::RuntimeObservability> = Arc::new(PanicRuntimeObservability);
144 let result = ep.create_producer(rt, &ctx);
145 assert!(result.is_err());
146 }
147
148 #[test]
150 fn component_context_noop_can_be_constructed() {
151 let _ctx = crate::NoOpComponentContext;
152 }
153
154 #[test]
155 fn component_context_noop_resolve_returns_none() {
156 let ctx = crate::NoOpComponentContext;
157 assert!(ctx.resolve_component("anything").is_none());
158 assert!(ctx.resolve_language("anything").is_none());
159 }
160}