parser.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. use async_std::sync::Arc;
  2. use std::collections::hash_map::Entry;
  3. use log::{debug, error, info};
  4. use serde_json::Value;
  5. use smol::Executor;
  6. use url::Url;
  7. use darkfi::util::NanoTimestamp;
  8. use crate::{
  9. config::DnvConfig,
  10. error::{DnetViewError, DnetViewResult},
  11. model::{ConnectInfo, Model, NodeInfo, SelectableObject, Session, SessionInfo},
  12. rpc::RpcConnect,
  13. util::{is_empty_session, make_connect_id, make_empty_id, make_node_id, make_session_id},
  14. };
  15. pub struct DataParser {
  16. model: Arc<Model>,
  17. config: DnvConfig,
  18. }
  19. impl DataParser {
  20. pub fn new(model: Arc<Model>, config: DnvConfig) -> Arc<Self> {
  21. Arc::new(Self { model, config })
  22. }
  23. pub async fn start_connect_slots(self: Arc<Self>, ex: Arc<Executor<'_>>) -> DnetViewResult<()> {
  24. debug!(target: "dnetview", "start_connect_slots() START");
  25. for node in &self.config.nodes {
  26. let self2 = self.clone();
  27. debug!(target: "dnetview", "attempting to spawn...");
  28. ex.clone().spawn(self2.try_connect(node.name.clone(), node.rpc_url.clone())).detach();
  29. }
  30. Ok(())
  31. }
  32. async fn try_connect(
  33. self: Arc<Self>,
  34. node_name: String,
  35. rpc_url: String,
  36. ) -> DnetViewResult<()> {
  37. debug!(target: "dnetview", "try_connect() START");
  38. loop {
  39. info!("Attempting to poll {}, RPC URL: {}", node_name, rpc_url);
  40. match RpcConnect::new(Url::parse(&rpc_url)?, node_name.clone()).await {
  41. Ok(client) => {
  42. self.poll(client).await?;
  43. }
  44. Err(e) => {
  45. error!("{}", e);
  46. self.parse_offline(node_name.clone()).await?;
  47. crate::util::sleep(2000).await;
  48. }
  49. }
  50. }
  51. }
  52. async fn poll(&self, client: RpcConnect) -> DnetViewResult<()> {
  53. loop {
  54. match client.ping().await {
  55. // TODO
  56. Ok(_reply) => {}
  57. Err(_e) => {}
  58. }
  59. match client.get_info().await {
  60. Ok(reply) => {
  61. if reply.as_object().is_some() && !reply.as_object().unwrap().is_empty() {
  62. self.parse_data(reply.as_object().unwrap(), &client).await?;
  63. } else {
  64. return Err(DnetViewError::EmptyRpcReply)
  65. }
  66. }
  67. Err(e) => {
  68. error!("{:?}", e);
  69. self.parse_offline(client.name.clone()).await?;
  70. }
  71. }
  72. crate::util::sleep(2000).await;
  73. }
  74. }
  75. async fn parse_offline(&self, node_name: String) -> DnetViewResult<()> {
  76. let name = "Offline".to_string();
  77. let session_type = Session::Offline;
  78. let node_id = make_node_id(&node_name)?;
  79. let session_id = make_session_id(&node_id, &session_type)?;
  80. let mut connects: Vec<ConnectInfo> = Vec::new();
  81. let mut sessions: Vec<SessionInfo> = Vec::new();
  82. // initialize with empty values
  83. let id = make_empty_id(&node_id, &session_type, 0)?;
  84. let addr = "Null".to_string();
  85. let state = "Null".to_string();
  86. let parent = node_id.clone();
  87. let msg_log = Vec::new();
  88. let is_empty = true;
  89. let last_msg = "Null".to_string();
  90. let last_status = "Null".to_string();
  91. let remote_node_id = "Null".to_string();
  92. let connect_info = ConnectInfo::new(
  93. id,
  94. addr,
  95. state.clone(),
  96. parent.clone(),
  97. msg_log,
  98. is_empty,
  99. last_msg,
  100. last_status,
  101. remote_node_id,
  102. );
  103. connects.push(connect_info.clone());
  104. let accept_addr = None;
  105. let session_info =
  106. SessionInfo::new(session_id, name, is_empty, parent.clone(), connects, accept_addr);
  107. sessions.push(session_info);
  108. let node = NodeInfo::new(
  109. node_id.clone(),
  110. node_name.to_string(),
  111. state.clone(),
  112. sessions.clone(),
  113. None,
  114. true,
  115. );
  116. self.update_selectable_and_ids(sessions, node.clone()).await?;
  117. self.update_id_vec().await;
  118. Ok(())
  119. }
  120. async fn parse_data(
  121. &self,
  122. reply: &serde_json::Map<String, Value>,
  123. client: &RpcConnect,
  124. ) -> DnetViewResult<()> {
  125. let addr = &reply.get("external_addr");
  126. let inbound = &reply["session_inbound"];
  127. let _manual = &reply["session_manual"];
  128. let outbound = &reply["session_outbound"];
  129. let state = &reply["state"];
  130. let mut sessions: Vec<SessionInfo> = Vec::new();
  131. let node_name = &client.name;
  132. let node_id = make_node_id(node_name)?;
  133. let ext_addr = self.parse_external_addr(addr).await?;
  134. let in_session = self.parse_inbound(inbound, &node_id).await?;
  135. let out_session = self.parse_outbound(outbound, &node_id).await?;
  136. //let man_session = self.parse_manual(manual, &node_id).await?;
  137. sessions.push(in_session.clone());
  138. sessions.push(out_session.clone());
  139. //sessions.push(man_session.clone());
  140. let node = NodeInfo::new(
  141. node_id.clone(),
  142. node_name.to_string(),
  143. state.as_str().unwrap().to_string(),
  144. sessions.clone(),
  145. ext_addr,
  146. false,
  147. );
  148. self.update_selectable_and_ids(sessions.clone(), node.clone()).await?;
  149. self.update_msgs(sessions.clone()).await?;
  150. self.update_id_vec().await;
  151. //debug!("IDS: {:?}", self.model.ids.lock().await);
  152. //debug!("INFOS: {:?}", self.model.nodes.lock().await);
  153. Ok(())
  154. }
  155. async fn update_msgs(&self, sessions: Vec<SessionInfo>) -> DnetViewResult<()> {
  156. for session in sessions {
  157. for connection in session.children {
  158. if !self.model.msg_map.lock().await.contains_key(&connection.id) {
  159. // we don't have this ID: it is a new node
  160. self.model
  161. .msg_map
  162. .lock()
  163. .await
  164. .insert(connection.id, connection.msg_log.clone());
  165. } else {
  166. // we have this id: append the msg values
  167. match self.model.msg_map.lock().await.entry(connection.id) {
  168. Entry::Vacant(e) => {
  169. e.insert(connection.msg_log);
  170. }
  171. Entry::Occupied(mut e) => {
  172. for msg in connection.msg_log {
  173. e.get_mut().push(msg);
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. Ok(())
  181. }
  182. async fn update_unique_ids(&self, id: String) {
  183. self.model.unique_ids.lock().await.insert(id);
  184. }
  185. async fn update_id_vec(&self) {
  186. let ids = self.model.unique_ids.lock().await.clone();
  187. for id in ids.iter() {
  188. self.model.id_vec.lock().await.push(id.to_string());
  189. }
  190. }
  191. async fn update_selectable_and_ids(
  192. &self,
  193. sessions: Vec<SessionInfo>,
  194. node: NodeInfo,
  195. ) -> DnetViewResult<()> {
  196. if node.is_offline == true {
  197. let node_obj = SelectableObject::Node(node.clone());
  198. self.model.selectables.lock().await.insert(node.id.clone(), node_obj);
  199. self.update_unique_ids(node.id.clone()).await;
  200. } else {
  201. let node_obj = SelectableObject::Node(node.clone());
  202. self.model.selectables.lock().await.insert(node.id.clone(), node_obj);
  203. self.update_unique_ids(node.id.clone()).await;
  204. for session in sessions {
  205. if !session.is_empty {
  206. let session_obj = SelectableObject::Session(session.clone());
  207. self.model.selectables.lock().await.insert(session.clone().id, session_obj);
  208. self.update_unique_ids(session.clone().id).await;
  209. for connect in session.children {
  210. let connect_obj = SelectableObject::Connect(connect.clone());
  211. self.model.selectables.lock().await.insert(connect.clone().id, connect_obj);
  212. self.update_unique_ids(connect.clone().id).await;
  213. }
  214. }
  215. }
  216. }
  217. Ok(())
  218. }
  219. async fn parse_external_addr(&self, addr: &Option<&Value>) -> DnetViewResult<Option<String>> {
  220. match addr {
  221. Some(addr) => match addr.as_str() {
  222. Some(addr) => Ok(Some(addr.to_string())),
  223. None => Ok(None),
  224. },
  225. None => Err(DnetViewError::NoExternalAddr),
  226. }
  227. }
  228. async fn parse_inbound(
  229. &self,
  230. inbound: &Value,
  231. node_id: &String,
  232. ) -> DnetViewResult<SessionInfo> {
  233. let name = "Inbound".to_string();
  234. let session_type = Session::Inbound;
  235. let parent = node_id.to_string();
  236. let id = make_session_id(&parent, &session_type)?;
  237. let mut connects: Vec<ConnectInfo> = Vec::new();
  238. let connections = &inbound["connected"];
  239. let mut connect_count = 0;
  240. let mut accept_vec = Vec::new();
  241. match connections.as_object() {
  242. Some(connect) => {
  243. match connect.is_empty() {
  244. true => {
  245. connect_count += 1;
  246. // channel is empty. initialize with empty values
  247. let id = make_empty_id(node_id, &session_type, connect_count)?;
  248. let addr = "Null".to_string();
  249. let state = "Null".to_string();
  250. let parent = parent.clone();
  251. let msg_log = Vec::new();
  252. let is_empty = true;
  253. let last_msg = "Null".to_string();
  254. let last_status = "Null".to_string();
  255. let remote_node_id = "Null".to_string();
  256. let connect_info = ConnectInfo::new(
  257. id,
  258. addr,
  259. state,
  260. parent,
  261. msg_log,
  262. is_empty,
  263. last_msg,
  264. last_status,
  265. remote_node_id,
  266. );
  267. connects.push(connect_info);
  268. }
  269. false => {
  270. // channel is not empty. initialize with whole values
  271. for k in connect.keys() {
  272. let node = connect.get(k);
  273. let addr = k.to_string();
  274. let info = node.unwrap().as_array();
  275. // get the accept address
  276. let accept_addr = info.unwrap().get(0);
  277. let acc_addr = accept_addr
  278. .unwrap()
  279. .get("accept_addr")
  280. .unwrap()
  281. .as_str()
  282. .unwrap()
  283. .to_string();
  284. accept_vec.push(acc_addr);
  285. let info2 = info.unwrap().get(1);
  286. let id = info2.unwrap().get("random_id").unwrap().as_u64().unwrap();
  287. let id = make_connect_id(&id)?;
  288. let state = "state".to_string();
  289. let parent = parent.clone();
  290. let msg_values = info2.unwrap().get("log").unwrap().as_array().unwrap();
  291. let mut msg_log: Vec<(NanoTimestamp, String, String)> = Vec::new();
  292. for msg in msg_values {
  293. let msg: (NanoTimestamp, String, String) =
  294. serde_json::from_value(msg.clone())?;
  295. msg_log.push(msg);
  296. }
  297. let is_empty = false;
  298. let last_msg = info2
  299. .unwrap()
  300. .get("last_msg")
  301. .unwrap()
  302. .as_str()
  303. .unwrap()
  304. .to_string();
  305. let last_status = info2
  306. .unwrap()
  307. .get("last_status")
  308. .unwrap()
  309. .as_str()
  310. .unwrap()
  311. .to_string();
  312. let remote_node_id = info2
  313. .unwrap()
  314. .get("remote_node_id")
  315. .unwrap()
  316. .as_str()
  317. .unwrap()
  318. .to_string();
  319. let r_node_id: String = match remote_node_id.is_empty() {
  320. true => "no remote id".to_string(),
  321. false => remote_node_id,
  322. };
  323. let connect_info = ConnectInfo::new(
  324. id,
  325. addr,
  326. state,
  327. parent,
  328. msg_log,
  329. is_empty,
  330. last_msg,
  331. last_status,
  332. r_node_id,
  333. );
  334. connects.push(connect_info.clone());
  335. }
  336. }
  337. }
  338. let is_empty = is_empty_session(&connects);
  339. // TODO: clean this up
  340. if accept_vec.is_empty() {
  341. let accept_addr = None;
  342. let session_info =
  343. SessionInfo::new(id, name, is_empty, parent, connects, accept_addr);
  344. Ok(session_info)
  345. } else {
  346. let accept_addr = Some(accept_vec[0].clone());
  347. let session_info =
  348. SessionInfo::new(id, name, is_empty, parent, connects, accept_addr);
  349. Ok(session_info)
  350. }
  351. }
  352. None => Err(DnetViewError::ValueIsNotObject),
  353. }
  354. }
  355. // TODO: placeholder for now
  356. async fn _parse_manual(
  357. &self,
  358. _manual: &Value,
  359. node_id: &String,
  360. ) -> DnetViewResult<SessionInfo> {
  361. let name = "Manual".to_string();
  362. let session_type = Session::Manual;
  363. let mut connects: Vec<ConnectInfo> = Vec::new();
  364. let parent = node_id.to_string();
  365. let session_id = make_session_id(&parent, &session_type)?;
  366. //let id: u64 = 0;
  367. let connect_id = make_empty_id(node_id, &session_type, 0)?;
  368. //let connect_id = make_connect_id(&id)?;
  369. let addr = "Null".to_string();
  370. let state = "Null".to_string();
  371. let msg_log = Vec::new();
  372. let is_empty = true;
  373. let msg = "Null".to_string();
  374. let status = "Null".to_string();
  375. let remote_node_id = "Null".to_string();
  376. let connect_info = ConnectInfo::new(
  377. connect_id.clone(),
  378. addr,
  379. state,
  380. parent,
  381. msg_log,
  382. is_empty,
  383. msg,
  384. status,
  385. remote_node_id,
  386. );
  387. connects.push(connect_info);
  388. let parent = connect_id;
  389. let is_empty = is_empty_session(&connects);
  390. let accept_addr = None;
  391. let session_info =
  392. SessionInfo::new(session_id, name, is_empty, parent, connects.clone(), accept_addr);
  393. Ok(session_info)
  394. }
  395. async fn parse_outbound(
  396. &self,
  397. outbound: &Value,
  398. node_id: &String,
  399. ) -> DnetViewResult<SessionInfo> {
  400. let name = "Outbound".to_string();
  401. let session_type = Session::Outbound;
  402. let parent = node_id.to_string();
  403. let id = make_session_id(&parent, &session_type)?;
  404. let mut connects: Vec<ConnectInfo> = Vec::new();
  405. let slots = &outbound["slots"];
  406. let mut slot_count = 0;
  407. match slots.as_array() {
  408. Some(slots) => {
  409. for slot in slots {
  410. slot_count += 1;
  411. match slot["channel"].is_null() {
  412. true => {
  413. // TODO: this is not actually empty
  414. let id = make_empty_id(node_id, &session_type, slot_count)?;
  415. let addr = "Null".to_string();
  416. let state = &slot["state"];
  417. let state = state.as_str().unwrap().to_string();
  418. let parent = parent.clone();
  419. let msg_log = Vec::new();
  420. let is_empty = false;
  421. let last_msg = "Null".to_string();
  422. let last_status = "Null".to_string();
  423. let remote_node_id = "Null".to_string();
  424. let connect_info = ConnectInfo::new(
  425. id,
  426. addr,
  427. state,
  428. parent,
  429. msg_log,
  430. is_empty,
  431. last_msg,
  432. last_status,
  433. remote_node_id,
  434. );
  435. connects.push(connect_info.clone());
  436. }
  437. false => {
  438. // channel is not empty. initialize with whole values
  439. let channel = &slot["channel"];
  440. let id = channel["random_id"].as_u64().unwrap();
  441. let id = make_connect_id(&id)?;
  442. let addr = &slot["addr"];
  443. let addr = addr.as_str().unwrap().to_string();
  444. let state = &slot["state"];
  445. let state = state.as_str().unwrap().to_string();
  446. let parent = parent.clone();
  447. let msg_values = channel["log"].as_array().unwrap();
  448. let mut msg_log: Vec<(NanoTimestamp, String, String)> = Vec::new();
  449. for msg in msg_values {
  450. let msg: (NanoTimestamp, String, String) =
  451. serde_json::from_value(msg.clone())?;
  452. msg_log.push(msg);
  453. }
  454. let is_empty = false;
  455. let last_msg = channel["last_msg"].as_str().unwrap().to_string();
  456. let last_status = channel["last_status"].as_str().unwrap().to_string();
  457. let remote_node_id =
  458. channel["remote_node_id"].as_str().unwrap().to_string();
  459. let r_node_id: String = match remote_node_id.is_empty() {
  460. true => "no remote id".to_string(),
  461. false => remote_node_id,
  462. };
  463. let connect_info = ConnectInfo::new(
  464. id,
  465. addr,
  466. state,
  467. parent,
  468. msg_log,
  469. is_empty,
  470. last_msg,
  471. last_status,
  472. r_node_id,
  473. );
  474. connects.push(connect_info.clone());
  475. }
  476. }
  477. }
  478. let is_empty = is_empty_session(&connects);
  479. let accept_addr = None;
  480. let session_info =
  481. SessionInfo::new(id, name, is_empty, parent, connects, accept_addr);
  482. Ok(session_info)
  483. }
  484. None => Err(DnetViewError::ValueIsNotObject),
  485. }
  486. }
  487. }