Skip to main content

camel_component_jms/
bundle.rs

1use std::sync::Arc;
2
3use camel_component_api::{CamelError, ComponentBundle, ComponentRegistrar};
4
5use crate::{JmsBridgePool, JmsComponent, config::JmsPoolConfig};
6
7/// Bundles the JMS component (jms/activemq/artemis schemes) with its pool lifecycle.
8pub struct JmsBundle {
9    pool: Arc<JmsBridgePool>,
10}
11
12impl JmsBundle {
13    pub fn new(cfg: JmsPoolConfig) -> Result<Self, CamelError> {
14        let pool =
15            JmsBridgePool::from_config(cfg).map_err(|e| CamelError::Config(e.to_string()))?;
16        Ok(Self {
17            pool: Arc::new(pool),
18        })
19    }
20
21    pub fn pool(&self) -> Arc<JmsBridgePool> {
22        Arc::clone(&self.pool)
23    }
24}
25
26impl ComponentBundle for JmsBundle {
27    fn config_key() -> &'static str {
28        "jms"
29    }
30
31    fn from_toml(value: toml::Value) -> Result<Self, CamelError> {
32        let cfg: JmsPoolConfig = value
33            .try_into()
34            .map_err(|e: toml::de::Error| CamelError::Config(e.to_string()))?;
35        Self::new(cfg)
36    }
37
38    fn register_all(self, ctx: &mut dyn ComponentRegistrar) {
39        ctx.register_component_dyn(Arc::new(JmsComponent::with_scheme(
40            "jms",
41            Arc::clone(&self.pool),
42        )));
43        ctx.register_component_dyn(Arc::new(JmsComponent::with_scheme(
44            "activemq",
45            Arc::clone(&self.pool),
46        )));
47        ctx.register_component_dyn(Arc::new(JmsComponent::with_scheme("artemis", self.pool)));
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    struct TestRegistrar {
56        schemes: Vec<String>,
57    }
58
59    impl camel_component_api::ComponentRegistrar for TestRegistrar {
60        fn register_component_dyn(
61            &mut self,
62            component: std::sync::Arc<dyn camel_component_api::Component>,
63        ) {
64            self.schemes.push(component.scheme().to_string());
65        }
66    }
67
68    #[test]
69    fn jms_bundle_from_toml_valid() {
70        let toml_str = r#"
71            [brokers.default]
72            broker_url = "tcp://localhost:61616"
73            broker_type = "activemq"
74        "#;
75        let value: toml::Value = toml::from_str(toml_str).expect("valid toml");
76        let result = JmsBundle::from_toml(value);
77        assert!(
78            result.is_ok(),
79            "valid JMS toml must parse: {:?}",
80            result.err()
81        );
82    }
83
84    #[test]
85    fn jms_bundle_registers_expected_schemes() {
86        let toml_str = r#"
87            [brokers.default]
88            broker_url = "tcp://localhost:61616"
89            broker_type = "activemq"
90        "#;
91        let value: toml::Value = toml::from_str(toml_str).expect("valid toml");
92        let bundle = JmsBundle::from_toml(value).expect("bundle from valid toml");
93        let mut registrar = TestRegistrar { schemes: vec![] };
94
95        bundle.register_all(&mut registrar);
96
97        assert_eq!(registrar.schemes, vec!["jms", "activemq", "artemis"]);
98    }
99
100    #[test]
101    fn jms_bundle_from_toml_returns_error_on_invalid_config() {
102        let mut table = toml::map::Map::new();
103        table.insert(
104            "max_bridges".to_string(),
105            toml::Value::String("not-a-number".to_string()),
106        );
107
108        let result = JmsBundle::from_toml(toml::Value::Table(table));
109        assert!(result.is_err(), "expected Err on malformed config");
110        let err_msg = match result {
111            Err(err) => err.to_string(),
112            Ok(_) => panic!("expected Err on malformed config"),
113        };
114        assert!(
115            err_msg.contains("Configuration error"),
116            "expected CamelError::Config, got: {err_msg}"
117        );
118    }
119}