sentinel_core/datasource/
property.rs

1use super::*;
2use serde_json;
3
4/// PropertyConverter func is to convert source message string to the specific property, that is, the sentinel rules.
5/// if succeed to convert src, return Ok(Property)
6/// if not, return the detailed error when convert src.
7/// if src is None or len(src)==0, the return value is Ok()
8pub type PropertyConverter<P> = fn(src: &str) -> Result<Vec<Arc<P>>>;
9
10// `rule_json_array_parser` provide JSON as the default serialization for list of flow::Rule
11pub fn rule_json_array_parser<P: SentinelRule + DeserializeOwned>(
12    src: &str,
13) -> Result<Vec<Arc<P>>> {
14    println!("{:?}", src);
15    println!("{:?}", serde_json::from_str::<Vec<P>>(src));
16    let rules: Vec<P> = serde_json::from_str(src)?;
17    Ok(rules.into_iter().map(|r| Arc::new(r)).collect())
18}
19
20/// PropertyUpdater func is to update the specific properties to downstream.
21/// return nil if succeed to update, if not, return the error.
22pub type PropertyUpdater<P> = fn(rule: Vec<Arc<P>>) -> Result<bool>;
23
24// todo: the updater in fact is the load method now,
25// the load method should be revised to a template method,
26
27pub trait PropertyHandler<P: SentinelRule>: Send + Sync {
28    // check whether the current src is consistent with last update property
29    fn is_property_consistent(&mut self, rules: &Vec<Arc<P>>) -> bool;
30    // handle the current property
31    fn handle(&mut self, src: Option<&String>) -> Result<bool>;
32    // update sentinel rules
33    fn load(&mut self, rules: Vec<Arc<P>>) -> Result<bool>;
34}
35
36/// DefaultPropertyHandler encapsulate the Converter and updater of property.
37/// One DefaultPropertyHandler instance is to handle one property type.
38/// DefaultPropertyHandler should check whether current property is consistent with last update property
39/// converter convert the message to the specific property
40/// updater update the specific property to downstream.
41pub struct DefaultPropertyHandler<P: SentinelRule + PartialEq + DeserializeOwned> {
42    last_update_property: Option<Vec<Arc<P>>>,
43    converter: PropertyConverter<P>,
44    updater: PropertyUpdater<P>,
45}
46
47impl<P: SentinelRule + PartialEq + DeserializeOwned> DefaultPropertyHandler<P> {
48    pub fn new(converter: PropertyConverter<P>, updater: PropertyUpdater<P>) -> Arc<Self> {
49        Arc::new(Self {
50            converter,
51            updater,
52            last_update_property: None,
53        })
54    }
55}
56
57impl<P: SentinelRule + PartialEq + DeserializeOwned> PropertyHandler<P>
58    for DefaultPropertyHandler<P>
59{
60    fn is_property_consistent<'a>(&mut self, rules: &'a Vec<Arc<P>>) -> bool {
61        if self.last_update_property.is_some()
62            && &self.last_update_property.as_ref().unwrap() == &rules
63        {
64            true
65        } else {
66            self.last_update_property = Some(rules.clone());
67            false
68        }
69    }
70
71    fn handle(&mut self, src: Option<&String>) -> Result<bool> {
72        match src {
73            Some(src) => {
74                let rules = (self.converter)(src)?;
75                let is_the_same = self.is_property_consistent(&rules);
76                if is_the_same {
77                    return Ok(false);
78                }
79                (self.updater)(rules)
80            }
81            None => (self.updater)(Vec::new()),
82        }
83    }
84
85    fn load(&mut self, rules: Vec<Arc<P>>) -> Result<bool> {
86        (self.updater)(rules)
87    }
88}