1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use super::Result;
use std::path::Path;

/// Supported dependency protocols
///
/// Forces lowercase values of this enum to be used
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "lowercase")]
pub enum DependencyProtocol {
    /// HTTP REST dependency
    Http,
    /// GRPC dependency
    Grpc,
    /// Kafka communication based dependency
    Kafka,
    /// RabbitMQ style dependency
    Amqp,
    /// Amazon SQS style dependency
    Sqs,
}
impl Default for DependencyProtocol {
    fn default() -> DependencyProtocol {
        DependencyProtocol::Http
    }
}

/// Dependency of a service
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[cfg_attr(feature = "filesystem", serde(deny_unknown_fields))]
pub struct Dependency {
    /// Name of service relied upon (used to goto dependent manifest)
    pub name: String,
    /// API version relied upon
    #[serde(default = "default_api_version")]
    pub api: String,
    /// Contract name for dependency
    pub contract: Option<String>,
    /// Protocol/message passing service used to depend on a service
    #[serde(default)]
    pub protocol: DependencyProtocol,
    /// Intent behind dependency - for manifest level descriptiveness
    pub intent: Option<String>,
}

fn default_api_version() -> String {
    "v1".into()
}

impl Dependency {
    pub fn verify(&self) -> Result<()> {
        // self.name must exist in services/
        let dpth = Path::new(".").join("services").join(self.name.clone());
        if !dpth.is_dir() {
            bail!("Service {} does not exist in services/", self.name);
        }
        if self.api != "" {
            let vstr = self.api.chars().skip_while(|ch| *ch == 'v').collect::<String>();
            let ver: usize = vstr.parse()?;
            trace!(
                "Parsed api version of dependency {} as {}",
                self.name.clone(),
                ver
            );
        }
        Ok(())
    }
}