bgpkit_commons/mrt_collectors/
mod.rs

1/*!
2Module for getting meta information for the public MRT mrt_collectors.
3
4Currently supported MRT collector projects:
5- RIPE RIS
6- RouteViews
7
8*/
9
10use crate::errors::{load_methods, modules};
11use crate::{BgpkitCommonsError, Result};
12use chrono::NaiveDateTime;
13use serde::{Deserialize, Serialize, Serializer};
14use std::cmp::Ordering;
15use std::fmt::{Display, Formatter};
16
17mod peers;
18mod riperis;
19mod routeviews;
20
21use crate::BgpkitCommons;
22pub use peers::{MrtCollectorPeer, get_mrt_collector_peers};
23pub use riperis::get_riperis_collectors;
24pub use routeviews::get_routeviews_collectors;
25
26/// MRT collector project enum
27#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
28pub enum MrtCollectorProject {
29    RouteViews,
30    RipeRis,
31}
32
33// Custom serialization function for the `age` field
34fn serialize_project<S>(
35    project: &MrtCollectorProject,
36    serializer: S,
37) -> std::result::Result<S::Ok, S::Error>
38where
39    S: Serializer,
40{
41    serializer.serialize_str(match project {
42        MrtCollectorProject::RouteViews => "routeview",
43        MrtCollectorProject::RipeRis => "riperis",
44    })
45}
46
47impl Display for MrtCollectorProject {
48    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49        match self {
50            MrtCollectorProject::RouteViews => {
51                write!(f, "routeviews")
52            }
53            MrtCollectorProject::RipeRis => {
54                write!(f, "riperis")
55            }
56        }
57    }
58}
59
60/// MRT collector meta information
61#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
62pub struct MrtCollector {
63    /// name of the collector
64    pub name: String,
65    /// collector project
66    #[serde(serialize_with = "serialize_project")]
67    pub project: MrtCollectorProject,
68    /// MRT data files root URL
69    pub data_url: String,
70    /// collector activation timestamp
71    pub activated_on: NaiveDateTime,
72    /// collector deactivation timestamp (None for active mrt_collectors)
73    pub deactivated_on: Option<NaiveDateTime>,
74    /// country where the collect runs in
75    pub country: String,
76}
77
78pub trait ToMrtCollector {
79    fn to_mrt_collector(&self) -> Option<MrtCollector>;
80}
81
82impl PartialOrd<Self> for MrtCollector {
83    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
84        Some(self.cmp(other))
85    }
86}
87
88impl Ord for MrtCollector {
89    fn cmp(&self, other: &Self) -> Ordering {
90        self.activated_on.cmp(&other.activated_on)
91    }
92}
93
94/// Get all MRT mrt_collectors from all data sources
95pub fn get_all_collectors() -> Result<Vec<MrtCollector>> {
96    let mut collectors = vec![];
97    collectors.extend(get_routeviews_collectors()?);
98    collectors.extend(get_riperis_collectors()?);
99    Ok(collectors)
100}
101
102impl BgpkitCommons {
103    pub fn mrt_collectors_all(&self) -> Result<Vec<MrtCollector>> {
104        if self.mrt_collectors.is_none() {
105            return Err(BgpkitCommonsError::module_not_loaded(
106                modules::MRT_COLLECTORS,
107                load_methods::LOAD_MRT_COLLECTORS,
108            ));
109        }
110        Ok(self.mrt_collectors.clone().unwrap())
111    }
112
113    pub fn mrt_collectors_by_name(&self, name: &str) -> Result<Option<MrtCollector>> {
114        if self.mrt_collectors.is_none() {
115            return Err(BgpkitCommonsError::module_not_loaded(
116                modules::MRT_COLLECTORS,
117                load_methods::LOAD_MRT_COLLECTORS,
118            ));
119        }
120        Ok(self
121            .mrt_collectors
122            .as_ref()
123            .unwrap()
124            .iter()
125            .find(|x| x.name == name)
126            .cloned())
127    }
128
129    pub fn mrt_collectors_by_country(&self, country: &str) -> Result<Vec<MrtCollector>> {
130        match &self.mrt_collectors {
131            Some(c) => Ok(c.iter().filter(|x| x.country == country).cloned().collect()),
132            None => Err(BgpkitCommonsError::module_not_loaded(
133                modules::MRT_COLLECTORS,
134                load_methods::LOAD_MRT_COLLECTORS,
135            )),
136        }
137    }
138
139    pub fn mrt_collector_peers_all(&self) -> Result<Vec<MrtCollectorPeer>> {
140        if self.mrt_collector_peers.is_none() {
141            return Err(BgpkitCommonsError::module_not_loaded(
142                modules::MRT_COLLECTOR_PEERS,
143                load_methods::LOAD_MRT_COLLECTOR_PEERS,
144            ));
145        }
146        Ok(self.mrt_collector_peers.clone().unwrap())
147    }
148
149    pub fn mrt_collector_peers_full_feed(&self) -> Result<Vec<MrtCollectorPeer>> {
150        if self.mrt_collector_peers.is_none() {
151            return Err(BgpkitCommonsError::module_not_loaded(
152                modules::MRT_COLLECTOR_PEERS,
153                load_methods::LOAD_MRT_COLLECTOR_PEERS,
154            ));
155        }
156        // Filter out mrt_collectors that have full feed
157        Ok(self
158            .mrt_collector_peers
159            .as_ref()
160            .unwrap()
161            .iter()
162            .filter(|x| x.is_full_feed())
163            .cloned()
164            .collect())
165    }
166}