use std::collections::HashMap; use anyhow::Result; use log::*; use serde::{Deserialize, Serialize}; // ---- Watch and retrieve Consul catalog ---- #[derive(Serialize, Deserialize, Debug)] pub struct ConsulServiceEntry { #[serde(rename = "Address")] pub address: String, #[serde(rename = "Port")] pub port: u16, #[serde(rename = "Tags")] pub tags: Vec, } #[derive(Serialize, Deserialize, Debug)] pub struct ConsulNodeCatalog { #[serde(rename = "Services")] pub services: HashMap, } #[derive(Clone)] pub struct Consul { client: reqwest::Client, url: String, idx: Option, } impl Consul { pub fn new(url: &str) -> Self { return Self { client: reqwest::Client::new(), url: url.to_string(), idx: None, }; } pub fn watch_node_reset(&mut self) -> () { self.idx = None; } pub async fn watch_node(&mut self, host: &str) -> Result { let url = match self.idx { Some(i) => format!("{}/v1/catalog/node/{}?index={}", self.url, host, i), None => format!("{}/v1/catalog/node/{}", self.url, host), }; let http = self.client.get(&url).send().await?; self.idx = match http.headers().get("X-Consul-Index") { Some(v) => Some(v.to_str()?.parse::()?), None => return Err(anyhow!("X-Consul-Index header not found")), }; let resp: ConsulNodeCatalog = http.json().await?; return Ok(resp); } }