north_common/registry/
default_service_instance.rs

1use crate::registry::service_instance::{ServiceInstance, ServiceInstanceOptions};
2use crate::registry::service_instance_state::ServiceInstanceState;
3use std::collections::HashMap;
4
5/// Base implementation of ServiceInstance
6#[derive(Default, Clone)]
7pub struct DefaultServiceInstance {
8    state: ServiceInstanceState,
9    options: ServiceInstanceOptions,
10}
11
12impl DefaultServiceInstance {
13    /// instantiates a new DefaultServiceInstance
14    pub fn new(opts: ServiceInstanceOptions) -> Self {
15        match &opts.state {
16            None => ServiceInstanceState::new(None),
17            Some(o) => o.clone(),
18        };
19
20        let mut options = opts;
21        let state = options.state.unwrap_or_default();
22        options.state = Some(state.clone());
23
24        DefaultServiceInstance { options, state }
25    }
26}
27
28impl ServiceInstance for DefaultServiceInstance {
29    fn get_instance_id(&self) -> String {
30        self.options.instance_id.clone()
31    }
32
33    fn get_service_id(&self) -> String {
34        self.options.service_id.clone()
35    }
36
37    fn get_host(&self) -> String {
38        self.options.host.clone()
39    }
40
41    fn get_port(&self) -> u32 {
42        self.options.port
43    }
44
45    fn is_secure(&self) -> bool {
46        self.options.secure
47    }
48
49    fn get_uri(&self) -> String {
50        let scheme = self.get_scheme();
51        let host = self.get_host();
52        let port = self.get_port();
53        format!(
54            "{scheme}://{host}:{port}",
55            scheme = scheme.as_str(),
56            host = host,
57            port = port
58        )
59    }
60
61    fn get_scheme(&self) -> String {
62        match self.is_secure() {
63            true => "https".to_string(),
64            false => "http".to_string(),
65        }
66    }
67
68    fn get_metadata(&self) -> HashMap<String, String> {
69        let opt: HashMap<String, String> = HashMap::new();
70        match self.options.clone().metadata {
71            None => opt,
72            Some(m) => m,
73        }
74    }
75
76    fn get_tags(&self) -> Vec<String> {
77        self.options.clone().tags.unwrap_or_default()
78    }
79
80    fn get_status(&self) -> String {
81        self.options.status.to_string()
82    }
83
84    fn get_node_id(&self) -> String {
85        self.options
86            .clone()
87            .node_id
88            .unwrap_or_else(|| self.get_instance_id())
89    }
90
91    fn get_state(self) -> ServiceInstanceState {
92        self.state
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use crate::registry::default_service_instance::DefaultServiceInstance;
99    use crate::registry::service_instance::{ServiceInstance, ServiceInstanceOptions};
100    use rstest::*;
101    use std::collections::HashMap;
102
103    #[fixture]
104    fn service_options() -> ServiceInstanceOptions {
105        let mut meta = HashMap::new();
106        meta.insert(String::from("region"), "USA".to_string());
107
108        ServiceInstanceOptions {
109            instance_id: "test-service-1".to_string(),
110            node_id: Some("test-node-1".to_string()),
111            service_id: "test-service".to_string(),
112            host: "127.0.5.0".to_string(),
113            status: Default::default(),
114            tags: Some(vec![String::from("service"), String::from("rust")]),
115            port: 8080,
116            secure: false,
117            state: None,
118            metadata: Some(meta),
119        }
120    }
121
122    #[fixture]
123    fn secure_service_options() -> ServiceInstanceOptions {
124        ServiceInstanceOptions {
125            instance_id: "test-service-1".to_string(),
126            node_id: Some("test-node-1".to_string()),
127            service_id: "test-service".to_string(),
128            host: "127.0.5.0".to_string(),
129            status: Default::default(),
130            tags: None,
131            port: 8080,
132            secure: true,
133            state: None,
134            metadata: None,
135        }
136    }
137
138    #[fixture]
139    fn service() -> DefaultServiceInstance {
140        DefaultServiceInstance::new(service_options())
141    }
142
143    #[fixture]
144    fn secure_service() -> DefaultServiceInstance {
145        DefaultServiceInstance::new(secure_service_options())
146    }
147
148    #[rstest]
149    fn it_can_get_service_host(service: DefaultServiceInstance) {
150        assert_eq!(service.get_host(), service_options().host);
151    }
152
153    #[rstest]
154    fn it_can_get_service_port(service: DefaultServiceInstance) {
155        assert_eq!(service.get_port(), service_options().port);
156    }
157
158    #[rstest]
159    fn it_can_check_service_secure(service: DefaultServiceInstance) {
160        assert_eq!(service.is_secure(), service_options().secure);
161    }
162
163    #[rstest]
164    #[case::secure(secure_service())]
165    #[case::insecure(service())]
166    fn it_can_check_service_scheme(#[case] service: DefaultServiceInstance) {
167        match service.is_secure() {
168            true => {
169                assert_eq!(service.get_scheme(), "https");
170            }
171            false => {
172                assert_eq!(service.get_scheme(), "http");
173            }
174        }
175    }
176
177    #[rstest]
178    #[case::secure(secure_service())]
179    #[case::insecure(service())]
180    fn it_can_check_service_uri(#[case] service: DefaultServiceInstance) {
181        match service.is_secure() {
182            true => {
183                assert_eq!(
184                    service.get_uri(),
185                    format!(
186                        "https://{host}:{port}",
187                        host = secure_service_options().host,
188                        port = secure_service_options().port
189                    )
190                );
191            }
192            false => {
193                assert_eq!(
194                    service.get_uri(),
195                    format!(
196                        "http://{host}:{port}",
197                        host = service_options().host,
198                        port = service_options().port
199                    )
200                );
201            }
202        }
203    }
204
205    #[rstest]
206    fn it_can_get_service_node_id(service: DefaultServiceInstance) {
207        assert_eq!(
208            service.get_node_id(),
209            service_options().node_id.unwrap_or_default()
210        );
211    }
212
213    #[rstest]
214    fn it_can_get_service_service_id(service: DefaultServiceInstance) {
215        assert_eq!(service.get_service_id(), service_options().service_id);
216    }
217
218    #[rstest]
219    fn it_can_get_service_instance_id(service: DefaultServiceInstance) {
220        assert_eq!(service.get_instance_id(), service_options().instance_id);
221    }
222
223    #[rstest]
224    fn it_can_get_service_tags(service: DefaultServiceInstance) {
225        assert_eq!(
226            service.get_tags(),
227            service_options().tags.unwrap_or_default()
228        );
229        assert_eq!(service.get_tags().len(), 2);
230    }
231
232    #[rstest]
233    fn it_can_get_service_metadata(service: DefaultServiceInstance) {
234        assert!(service.get_metadata().contains_key("region"));
235        assert_eq!(
236            service.get_metadata(),
237            service_options().metadata.unwrap_or_default()
238        );
239    }
240}