#![no_std]
extern crate no_std_compat as std;
use std::prelude::v1::*;
#[macro_use]
extern crate mopa;
pub use async_trait::async_trait;
use std::fmt::{Debug, Formatter};
use std::sync::Arc;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
mod features;
mod services;
pub use features::Features;
use product_os_router::{Body, ProductOSRouter, Request, Response};
pub use services::Services;
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RegistryFeature {
pub identifier: String,
pub paths: Vec<String>,
#[serde(skip, default = "default_feature")]
pub feature: Option<Arc<dyn Feature>>,
#[serde(skip, default = "default_feature_mut")]
pub feature_mut: Option<Arc<Mutex<dyn Feature>>>
}
impl Debug for RegistryFeature {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Identifier: {}\nPaths: {:?}\n", self.identifier, self.paths)
}
}
impl RegistryFeature {
}
fn default_feature() -> Option<Arc<dyn Feature>> {
Some(Arc::new(DefaultFeature {}))
}
fn default_feature_mut() -> Option<Arc<Mutex<dyn Feature>>> {
Some(Arc::new(Mutex::new(DefaultFeature {})))
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RegistryService {
pub identifier: String,
pub key: String,
#[serde(rename = "type")]
pub kind: String,
pub active: bool,
pub enabled: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip, default = "default_service")]
pub service: Option<Arc<dyn Service>>,
#[serde(skip, default = "default_service_mut")]
pub service_mut: Option<Arc<Mutex<dyn Service>>>
}
impl Debug for RegistryService {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Identifier: {}\nKey: {}\nEnabled: {}\nActive:{:?}", self.identifier, self.key, self.enabled, self.active)
}
}
impl RegistryService {
pub fn identifier(&self) -> String {
self.identifier.to_owned()
}
pub fn key(&self) -> String {
self.key.to_owned()
}
pub fn is_enabled(&self) -> bool {
self.enabled
}
pub fn is_active(&self) -> bool {
self.active
}
pub async fn status(&self) -> Result<(), ()> {
match &self.service {
Some(service) => service.status().await,
None => {
match &self.service_mut {
Some(service) => {
let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
match service_locked {
None => Err(()),
Some(service) => service.status().await
}
}
None => Err(())
}
}
}
}
pub async fn init(&mut self) -> Result<(), ()> {
match &self.service {
Some(service) => service.init_service().await,
None => {
match &self.service_mut {
Some(service) => {
let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
match service_locked {
None => Err(()),
Some(mut service) => service.init_service_mut().await
}
}
None => Err(())
}
}
}
}
pub async fn start(&mut self) -> Result<(), ()> {
match &self.service {
Some(service) => service.start().await,
None => {
match &self.service_mut {
Some(service) => {
let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
match service_locked {
None => Err(()),
Some(mut service) => service.start_mut().await
}
}
None => Err(())
}
}
}
}
pub async fn stop(&mut self) -> Result<(), ()> {
match &self.service {
Some(service) => service.stop().await,
None => {
match &self.service_mut {
Some(service) => {
let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
match service_locked {
None => Err(()),
Some(mut service) => service.stop_mut().await
}
}
None => Err(())
}
}
}
}
pub async fn restart(&mut self) -> Result<(), ()> {
match &self.service {
Some(service) => service.restart().await,
None => {
match &self.service_mut {
Some(service) => {
let service_locked = service.try_lock_for(core::time::Duration::new(10, 0));
match service_locked {
None => Err(()),
Some(mut service) => service.restart_mut().await
}
}
None => Err(())
}
}
}
}
}
fn default_service() -> Option<Arc<dyn Service>> {
Some(Arc::new(DefaultService {}))
}
fn default_service_mut() -> Option<Arc<Mutex<dyn Service>>> {
Some(Arc::new(Mutex::new(DefaultService {})))
}
#[async_trait]
pub trait Feature: Send + Sync + mopa::Any {
async fn register(&self, feature: Arc<dyn Feature>, base_path: String, router: &mut product_os_router::ProductOSRouter) -> RegistryFeature;
async fn register_mut(&self, feature: Arc<Mutex<dyn Feature>>, base_path: String, router: &mut product_os_router::ProductOSRouter) -> RegistryFeature;
fn identifier(&self) -> String;
async fn request(&self, request: Request<Body>, version: String) -> Response<Body>;
async fn request_mut(&mut self, request: Request<Body>, version: String) -> Response<Body>;
async fn init_feature(&self) -> Result<(), ()> { Ok(()) }
async fn init_feature_mut(&mut self) -> Result<(), ()> { Ok(()) }
}
mopafy!(Feature);
pub struct DefaultFeature {}
#[async_trait]
impl Feature for DefaultFeature {
async fn register(&self, feature: Arc<dyn Feature>, _: String, _: &mut ProductOSRouter) -> RegistryFeature {
RegistryFeature {
identifier: "".to_string(),
paths: vec![],
feature: Some(feature),
feature_mut: None
}
}
async fn register_mut(&self, feature: Arc<Mutex<dyn Feature>>, _: String, _: &mut ProductOSRouter) -> RegistryFeature {
RegistryFeature {
identifier: "".to_string(),
paths: vec![],
feature: None,
feature_mut: Some(feature)
}
}
fn identifier(&self) -> String {
"default".to_string()
}
async fn request(&self, _: Request<Body>, _: String) -> Response<Body> {
Response::default()
}
async fn request_mut(&mut self, _: Request<Body>, _: String) -> Response<Body> {
Response::default()
}
}
#[async_trait]
pub trait Service: Send + Sync + mopa::Any {
async fn register(&self, service: Arc<dyn Service>) -> RegistryService;
async fn register_mut(&self, service: Arc<Mutex<dyn Service>>) -> RegistryService;
fn identifier(&self) -> String;
fn key(&self) -> String;
fn is_enabled(&self) -> bool;
fn is_active(&self) -> bool;
async fn status(&self) -> Result<(), ()>;
async fn init_service(&self) -> Result<(), ()> { Ok(()) }
async fn start(&self) -> Result<(), ()>;
async fn stop(&self) -> Result<(), ()>;
async fn restart(&self) -> Result<(), ()>;
async fn init_service_mut(&mut self) -> Result<(), ()> { Ok(()) }
async fn start_mut(&mut self) -> Result<(), ()>;
async fn stop_mut(&mut self) -> Result<(), ()>;
async fn restart_mut(&mut self) -> Result<(), ()>;
}
mopafy!(Service);
pub struct DefaultService {}
#[async_trait]
impl Service for DefaultService {
async fn register(&self, service: Arc<dyn Service>) -> RegistryService {
RegistryService {
identifier: "".to_string(),
key: "".to_string(),
kind: "".to_string(),
active: false,
enabled: false,
created_at: Utc::now(),
updated_at: Utc::now(),
service: Some(service),
service_mut: None
}
}
async fn register_mut(&self, service: Arc<Mutex<dyn Service>>) -> RegistryService {
RegistryService {
identifier: "".to_string(),
key: "".to_string(),
kind: "".to_string(),
active: false,
enabled: false,
created_at: Utc::now(),
updated_at: Utc::now(),
service: None,
service_mut: Some(service)
}
}
fn identifier(&self) -> String {
"default".to_string()
}
fn key(&self) -> String {
"key".to_string()
}
fn is_enabled(&self) -> bool {
false
}
fn is_active(&self) -> bool {
false
}
async fn status(&self) -> Result<(), ()> { Ok(()) }
async fn init_service(&self) -> Result<(), ()> { Ok(()) }
async fn start(&self) -> Result<(), ()> { Ok(()) }
async fn stop(&self) -> Result<(), ()> { Ok(()) }
async fn restart(&self) -> Result<(), ()> { Ok(()) }
async fn init_service_mut(&mut self) -> Result<(), ()> { Ok(()) }
async fn start_mut(&mut self) -> Result<(), ()> { Ok(()) }
async fn stop_mut(&mut self) -> Result<(), ()> { Ok(()) }
async fn restart_mut(&mut self) -> Result<(), ()> { Ok(()) }
}
#[cfg(feature = "feature_service")]
pub trait FeatureService: Feature + Service {}