grapl_graph_descriptions/
process_inbound_connection.rs1use std::convert::TryFrom;
2
3use log::warn;
4use serde_json::{json, Value};
5use uuid::Uuid;
6
7use crate::error::Error;
8use crate::graph_description::ProcessInboundConnection;
9use crate::node::NodeT;
10
11pub enum ProcessInboundConnectionState {
12 Bound,
13 Existing,
14 Closed,
15}
16
17impl From<ProcessInboundConnectionState> for u32 {
18 fn from(p: ProcessInboundConnectionState) -> u32 {
19 match p {
20 ProcessInboundConnectionState::Bound => 1,
21 ProcessInboundConnectionState::Closed => 2,
22 ProcessInboundConnectionState::Existing => 3,
23 }
24 }
25}
26
27impl TryFrom<u32> for ProcessInboundConnectionState {
28 type Error = Error;
29
30 fn try_from(p: u32) -> Result<ProcessInboundConnectionState, Error> {
31 match p {
32 1 => Ok(ProcessInboundConnectionState::Bound),
33 2 => Ok(ProcessInboundConnectionState::Closed),
34 3 => Ok(ProcessInboundConnectionState::Existing),
35 _ => Err(Error::InvalidProcessInboundConnectionState(p)),
36 }
37 }
38}
39
40impl ProcessInboundConnection {
41 pub fn new(
42 asset_id: impl Into<Option<String>>,
43 hostname: impl Into<Option<String>>,
44 state: ProcessInboundConnectionState,
45 port: u16,
46 ip_address: impl Into<String>,
47 protocol: impl Into<String>,
48 created_timestamp: u64,
49 terminated_timestamp: u64,
50 last_seen_timestamp: u64,
51 ) -> Self {
52 let asset_id = asset_id.into();
53 let hostname = hostname.into();
54 let protocol = protocol.into();
55
56 if hostname.is_none() && asset_id.is_none() {
57 panic!("ProcessInboundConnection must have at least asset_id or hostname");
58 }
59
60 let ip_address = ip_address.into();
61
62 Self {
63 node_key: Uuid::new_v4().to_string(),
64 ip_address,
65 asset_id,
66 hostname,
67 protocol,
68 created_timestamp,
69 terminated_timestamp,
70 last_seen_timestamp,
71 port: port as u32,
72 state: state.into(),
73 }
74 }
75
76 pub fn into_json(self) -> Value {
77 let mut j = json!({
78 "node_key": self.node_key,
79 "dgraph.type": "ProcessInboundConnection",
80 "protocol": self.protocol,
81 "port": self.port,
82 });
83
84 if self.created_timestamp != 0 {
85 j["created_timestamp"] = self.created_timestamp.into();
86 }
87 if self.terminated_timestamp != 0 {
88 j["terminated_timestamp"] = self.terminated_timestamp.into();
89 }
90 if self.last_seen_timestamp != 0 {
91 j["last_seen_timestamp"] = self.last_seen_timestamp.into();
92 }
93
94 j
95 }
96}
97
98impl NodeT for ProcessInboundConnection {
99 fn get_asset_id(&self) -> Option<&str> {
100 self.asset_id.as_ref().map(String::as_str)
101 }
102
103 fn set_asset_id(&mut self, asset_id: impl Into<String>) {
104 self.asset_id = Some(asset_id.into());
105 }
106
107 fn get_node_key(&self) -> &str {
108 &self.node_key
109 }
110
111 fn set_node_key(&mut self, node_key: impl Into<String>) {
112 self.node_key = node_key.into();
113 }
114
115 fn merge(&mut self, other: &Self) -> bool {
116 if self.node_key != other.node_key {
117 warn!("Attempted to merge two ProcessInboundConnection Nodes with differing node_keys");
118 return false;
119 }
120
121 if self.ip_address != other.ip_address {
122 warn!("Attempted to merge two ProcessInboundConnection Nodes with differing IPs");
123 return false;
124 }
125
126 let mut merged = false;
127
128 if self.asset_id.is_none() && other.asset_id.is_some() {
129 self.asset_id = other.asset_id.clone();
130 }
131
132 if self.hostname.is_none() && other.hostname.is_some() {
133 self.hostname = other.hostname.clone();
134 }
135
136 if self.created_timestamp != 0 && self.created_timestamp > other.created_timestamp {
137 self.created_timestamp = other.created_timestamp;
138 merged = true;
139 }
140
141 if self.terminated_timestamp != 0 && self.terminated_timestamp < other.terminated_timestamp
142 {
143 self.terminated_timestamp = other.terminated_timestamp;
144 merged = true;
145 }
146
147 if self.last_seen_timestamp != 0 && self.last_seen_timestamp < other.last_seen_timestamp {
148 self.last_seen_timestamp = other.last_seen_timestamp;
149 merged = true;
150 }
151
152 merged
153 }
154
155 fn merge_into(&mut self, other: Self) -> bool {
156 self.merge(&other)
157 }
158}