product_os_capabilities/
lib.rs

1#![no_std]
2extern crate no_std_compat as std;
3
4use std::prelude::v1::*;
5
6#[macro_use]
7extern crate mopa;
8
9
10pub use async_trait::async_trait;
11
12use std::fmt::{Debug, Formatter};
13use std::sync::Arc;
14use parking_lot::Mutex;
15
16use serde::{Deserialize, Serialize};
17use chrono::{DateTime, Utc};
18
19mod features;
20mod services;
21
22pub use features::Features;
23use product_os_router::{Body, ProductOSRouter, Request, Response};
24pub use services::Services;
25
26
27
28
29#[derive(Deserialize, Serialize)]
30#[serde(rename_all = "camelCase")]
31pub struct RegistryFeature {
32    pub identifier: String,
33    pub paths: Vec<String>,
34    #[serde(skip, default = "default_feature")]
35    pub feature: Option<Arc<dyn Feature>>,
36    #[serde(skip, default = "default_feature_mut")]
37    pub feature_mut: Option<Arc<Mutex<dyn Feature>>>
38}
39
40impl Debug for RegistryFeature {
41    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42        write!(f, "Identifier: {}\nPaths: {:?}\n", self.identifier, self.paths)
43    }
44}
45
46impl RegistryFeature {
47
48}
49
50fn default_feature() -> Option<Arc<dyn Feature>> {
51    Some(Arc::new(DefaultFeature {}))
52}
53
54fn default_feature_mut() -> Option<Arc<Mutex<dyn Feature>>> {
55    Some(Arc::new(Mutex::new(DefaultFeature {})))
56}
57
58
59
60#[derive(Deserialize, Serialize)]
61#[serde(rename_all = "camelCase")]
62pub struct RegistryService {
63    pub identifier: String,
64    pub key: String,
65    #[serde(rename = "type")]
66    pub kind: String,
67    pub active: bool,
68    pub enabled: bool,
69    pub created_at: DateTime<Utc>,
70    pub updated_at: DateTime<Utc>,
71    #[serde(skip, default = "default_service")]
72    pub service: Option<Arc<dyn Service>>,
73    #[serde(skip, default = "default_service_mut")]
74    pub service_mut: Option<Arc<Mutex<dyn Service>>>
75}
76
77impl Debug for RegistryService {
78    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
79        write!(f, "Identifier: {}\nKey: {}\nEnabled: {}\nActive:{:?}", self.identifier, self.key, self.enabled, self.active)
80    }
81}
82
83impl RegistryService {
84    pub fn identifier(&self) -> String {
85        self.identifier.to_owned()
86    }
87
88    pub fn key(&self) -> String {
89        self.key.to_owned()
90    }
91
92    pub fn is_enabled(&self) -> bool {
93        self.enabled
94    }
95
96    pub fn is_active(&self) -> bool {
97        self.active
98    }
99
100    pub async fn status(&self) -> Result<(), ()> {
101        match &self.service {
102            Some(service) => service.status().await,
103            None => {
104                match &self.service_mut {
105                    Some(service) => {
106                        let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
107
108                        match service_locked {
109                            None => Err(()),
110                            Some(service) => service.status().await
111                        }
112                    }
113                    None => Err(())
114                }
115            }
116        }
117    }
118
119    pub async fn init(&mut self) -> Result<(), ()> {
120        match &self.service {
121            Some(service) => service.init_service().await,
122            None => {
123                match &self.service_mut {
124                    Some(service) => {
125                        let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
126
127                        match service_locked {
128                            None => Err(()),
129                            Some(mut service) => service.init_service_mut().await
130                        }
131                    }
132                    None => Err(())
133                }
134            }
135        }
136    }
137
138    pub async fn start(&mut self) -> Result<(), ()> {
139        match &self.service {
140            Some(service) => service.start().await,
141            None => {
142                match &self.service_mut {
143                    Some(service) => {
144                        let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
145
146                        match service_locked {
147                            None => Err(()),
148                            Some(mut service) => service.start_mut().await
149                        }
150                    }
151                    None => Err(())
152                }
153            }
154        }
155    }
156
157    pub async fn stop(&mut self) -> Result<(), ()> {
158        match &self.service {
159            Some(service) => service.stop().await,
160            None => {
161                match &self.service_mut {
162                    Some(service) => {
163                        let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
164
165                        match service_locked {
166                            None => Err(()),
167                            Some(mut service) => service.stop_mut().await
168                        }
169                    }
170                    None => Err(())
171                }
172            }
173        }
174    }
175
176    pub async fn restart(&mut self) -> Result<(), ()> {
177        match &self.service {
178            Some(service) => service.restart().await,
179            None => {
180                match &self.service_mut {
181                    Some(service) => {
182                        let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
183
184                        match service_locked {
185                            None => Err(()),
186                            Some(mut service) => service.restart_mut().await
187                        }
188                    }
189                    None => Err(())
190                }
191            }
192        }
193    }
194}
195
196
197fn default_service() -> Option<Arc<dyn Service>> {
198    Some(Arc::new(DefaultService {}))
199}
200
201
202fn default_service_mut() -> Option<Arc<Mutex<dyn Service>>> {
203    Some(Arc::new(Mutex::new(DefaultService {})))
204}
205
206
207
208#[async_trait]
209pub trait Feature: Send + Sync + mopa::Any {
210    async fn register(&self, feature: Arc<dyn Feature>, base_path: String, router: &mut product_os_router::ProductOSRouter) -> RegistryFeature;
211    async fn register_mut(&self, feature: Arc<Mutex<dyn Feature>>, base_path: String, router: &mut product_os_router::ProductOSRouter) -> RegistryFeature;
212    fn identifier(&self) -> String;
213    async fn request(&self, request: Request<Body>, version: String) -> Response<Body>;
214    async fn request_mut(&mut self, request: Request<Body>, version: String) -> Response<Body>;
215    async fn init_feature(&self) -> Result<(), ()> { Ok(()) }
216    async fn init_feature_mut(&mut self) -> Result<(), ()> { Ok(()) }
217}
218
219mopafy!(Feature);
220
221pub struct DefaultFeature {}
222
223#[async_trait]
224impl Feature for DefaultFeature {
225    async fn register(&self, feature: Arc<dyn Feature>, _: String, _: &mut ProductOSRouter) -> RegistryFeature {
226        RegistryFeature {
227            identifier: "".to_string(),
228            paths: vec![],
229            feature: Some(feature),
230            feature_mut: None
231        }
232    }
233
234    async fn register_mut(&self, feature: Arc<Mutex<dyn Feature>>, _: String, _: &mut ProductOSRouter) -> RegistryFeature {
235        RegistryFeature {
236            identifier: "".to_string(),
237            paths: vec![],
238            feature: None,
239            feature_mut: Some(feature)
240        }
241    }
242
243    fn identifier(&self) -> String {
244        "default".to_string()
245    }
246
247    async fn request(&self, _: Request<Body>, _: String) -> Response<Body> {
248        Response::default()
249    }
250
251    async fn request_mut(&mut self, _: Request<Body>, _: String) -> Response<Body> {
252        Response::default()
253    }
254}
255
256
257#[async_trait]
258pub trait Service: Send + Sync + mopa::Any {
259    async fn register(&self, service: Arc<dyn Service>) -> RegistryService;
260    async fn register_mut(&self, service: Arc<Mutex<dyn Service>>) -> RegistryService;
261    fn identifier(&self) -> String;
262    fn key(&self) -> String;
263    fn is_enabled(&self) -> bool;
264    fn is_active(&self) -> bool;
265    async fn status(&self) -> Result<(), ()>;
266    async fn init_service(&self) -> Result<(), ()> { Ok(()) }
267    async fn start(&self) -> Result<(), ()>;
268    async fn stop(&self) -> Result<(), ()>;
269    async fn restart(&self) -> Result<(), ()>;
270    async fn init_service_mut(&mut self) -> Result<(), ()> { Ok(()) }
271    async fn start_mut(&mut self) -> Result<(), ()>;
272    async fn stop_mut(&mut self) -> Result<(), ()>;
273    async fn restart_mut(&mut self) -> Result<(), ()>;
274}
275
276mopafy!(Service);
277
278pub struct DefaultService {}
279
280#[async_trait]
281impl Service for DefaultService {
282    async fn register(&self, service: Arc<dyn Service>) -> RegistryService {
283        RegistryService {
284            identifier: "".to_string(),
285            key: "".to_string(),
286            kind: "".to_string(),
287            active: false,
288            enabled: false,
289            created_at: Utc::now(),
290            updated_at: Utc::now(),
291            service: Some(service),
292            service_mut: None
293        }
294    }
295
296    async fn register_mut(&self, service: Arc<Mutex<dyn Service>>) -> RegistryService {
297        RegistryService {
298            identifier: "".to_string(),
299            key: "".to_string(),
300            kind: "".to_string(),
301            active: false,
302            enabled: false,
303            created_at: Utc::now(),
304            updated_at: Utc::now(),
305            service: None,
306            service_mut: Some(service)
307        }
308    }
309
310    fn identifier(&self) -> String {
311        "default".to_string()
312    }
313
314    fn key(&self) -> String {
315        "key".to_string()
316    }
317
318    fn is_enabled(&self) -> bool {
319        false
320    }
321
322    fn is_active(&self) -> bool {
323        false
324    }
325
326    async fn status(&self) -> Result<(), ()> { Ok(()) }
327
328    async fn init_service(&self) -> Result<(), ()> { Ok(()) }
329
330    async fn start(&self) -> Result<(), ()> { Ok(()) }
331
332    async fn stop(&self) -> Result<(), ()> { Ok(()) }
333
334    async fn restart(&self) -> Result<(), ()> { Ok(()) }
335
336    async fn init_service_mut(&mut self) -> Result<(), ()> { Ok(()) }
337
338    async fn start_mut(&mut self) -> Result<(), ()> { Ok(()) }
339
340    async fn stop_mut(&mut self) -> Result<(), ()> { Ok(()) }
341
342    async fn restart_mut(&mut self) -> Result<(), ()> { Ok(()) }
343}
344
345
346#[cfg(feature = "feature_service")]
347pub trait FeatureService: Feature + Service {}