integration-module/crates/integr-structs/src/api.rs

488 lines
13 KiB
Rust

use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use serde_json::{ to_string_pretty, Value };
use anyhow::Result;
use std::sync::Arc;
use std::fmt::Display;
use chrono::{DateTime, Local};
#[derive(Serialize, Deserialize, Debug)]
pub struct ApiConfig {
#[serde(default)]
pub endpoints : Vec<ApiEndpoint>,
pub delay : u32,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ApiEndpoint {
pub url : String,
pub method : String,
}
impl Default for ApiConfig {
fn default() -> Self {
ApiConfig {
endpoints : vec![],
delay : 0,
}
}
}
// v2
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ApiConfigV2 {
pub id : u64,
#[serde(default)]
pub template : Vec<Template>,
pub ip_address : String,
pub login : Option<String>,
pub pass : Option<String>,
pub api_key : Option<String>,
pub period : u32, // if "0" -> inf
pub timeout : u32, // if "0" -> no-delay
}
impl Default for ApiConfigV2 {
fn default() -> Self {
ApiConfigV2 {
id : 0,
template : Vec::new(),
ip_address : String::from("no_ip"),
login : None,
pass : None,
api_key : None,
period : 0,
timeout : 0,
}
}
}
impl ApiConfigV2 {
pub fn template() -> Self {
ApiConfigV2 {
id : 1111,
template : Vec::new(),
ip_address : String::from("ip"),
login : None,
pass : None,
api_key : None,
period : 1111,
timeout : 1111,
}
}
pub fn pattern() -> Self {
ApiConfigV2 {
id : 1111,
template : vec![
Template {
id : String::from("no id"),
name : String::from("open api"),
url : String::from("https://dummy-json.mock.beeceptor.com/countries"),
method : String::from("GET"),
measure : Vec::new(),
}
],
ip_address : String::from("ip"),
login : None,
pass : None,
api_key : None,
period : 1,
timeout : 1,
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Template {
pub id : String,
pub name : String,
pub url : String,
pub method : String,
#[serde(default)]
pub measure : Vec<String>,
}
impl Default for Template {
fn default() -> Self {
Template {
id : String::from("no-id"),
name : String::from("no-name"),
url : String::from("no-url"),
method : String::from("post"),
measure : Vec::new(),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ProcessedEndpoint {
id : String,
name : String,
url : String,
method : String,
#[serde(default)]
metrics : HashMap<String, Value>,
}
impl ProcessedEndpoint {
pub fn new(id: &str, name: &str, url: &str, method: &str, metrics: HashMap<String, Value>) -> Self {
ProcessedEndpoint {
id : id.to_owned(),
name : name.to_owned(),
url : url.to_owned(),
method : method.to_owned(),
metrics : metrics,
}
}
pub fn from_target_response(response: &str, keys: &Template) -> Result<String> {
let mut hm: HashMap<String, Value> = HashMap::new();
let mut response: Value = serde_json::from_str(response)?;
let _ = keys.measure.iter()
.map(|key| (key, response[key].take()))
.for_each(|(key, value)| {
hm.insert(key.clone(), value);
});
let val = ProcessedEndpoint::new(&keys.id, &keys.name, &keys.url, &keys.method,hm);
Ok(to_string_pretty(&val)?)
}
}
pub mod v3 {
pub use super::*;
// in config
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Metric {
pub id : String,
#[serde(rename = "type")]
pub json_type : String,
pub addr : String,
}
impl Metric {
pub fn template() -> Self {
Self {
id : "room_tempo".to_string(),
json_type : "String".to_string(),
addr : "flat1.room1.rt_tempo".to_string(),
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Metrics {
pub name : String,
pub url : String,
#[serde(default)]
pub measure : Vec<Metric>
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ConfigEndpoint {
pub id : String,
pub login : String,
#[serde(rename = "pass")]
pub password : String,
pub api_key : String,
period : String,
timeout : String,
#[serde(default)]
pub metrics : Vec<Metrics>,
}
impl ConfigEndpoint {
pub fn from_config(config: Arc<Config>) -> Vec<Arc<Self>> {
let mut result: Vec<Arc<ConfigEndpoint>> = Vec::new();
config.config
.iter()
.for_each(|el| {
result.push(Arc::new(el.clone()))
});
result
}
pub fn get_period(&self) -> Option<u32> {
self.period.parse().ok()
}
pub fn get_timeout(&self) -> Option<u64> {
self.timeout.parse().ok()
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Config {
pub config : Vec<ConfigEndpoint>,
}
impl Default for Config {
fn default() -> Self {
Self {
config : Vec::new()
}
}
}
impl Config {
pub async fn is_default(&self) -> bool {
self.config.is_empty()
}
}
#[derive(Clone)]
pub struct Credentials {
pub endpoint : Arc<ConfigEndpoint>,
}
impl Credentials {
pub fn from_config_endpoint(endpoint: Arc<ConfigEndpoint>) -> Credentials {
Self { endpoint }
}
// pub fn clone(self) -> Self {
// Self {
// endpoint : self.endpoint.clone()
// }
// }
}
// to prometheus and nmns
#[derive(Serialize, Deserialize, Debug)]
pub struct MetricOutput {
pub id : String,
#[serde(rename = "type")]
pub json_type : String,
pub addr : String,
pub value : Value,
}
impl MetricOutput {
pub fn new_with_slices(id : &str, json_type : &str, addr: &str, value : Value) -> Self {
MetricOutput {
id : id.to_string(),
json_type : json_type.to_string(),
addr : addr.to_string(),
value : value,
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct MetricOutputExtended {
pub id : String,
#[serde(rename = "type")]
pub json_type : String,
pub addr : String,
pub value : Value,
#[serde(rename = "description")]
pub desc : String,
}
impl MetricOutputExtended {
pub fn new_with_slices(id : &str, json_type : &str, addr: &str, desc : &str, value : Value) -> Self {
MetricOutputExtended {
id : id.to_string(),
json_type : json_type.to_string(),
addr : addr.to_string(),
value : value,
desc : desc.to_string(),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PrometheusMetrics {
pub service_name: String,
pub endpoint_name: String,
pub metrics: Vec<MetricOutput>,
}
impl PrometheusMetrics {
pub fn new(service: &str, endpoint: &str, metrics: Vec<MetricOutput>) -> Self {
Self {
service_name: service.to_string(),
endpoint_name: endpoint.to_string(),
metrics: metrics
}
}
pub async fn new_zvks(metrics: Vec<MetricOutput>) -> Self {
Self {
service_name : "zvks".to_owned(),
endpoint_name : "apiforsnmp".to_owned(),
metrics : metrics,
}
}
pub fn get_bytes_len(&self) -> usize {
let str_metrics = serde_json::to_vec(self).unwrap_or_else(
|_| Vec::new()
);
str_metrics.len()
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PrometheusMetricsExtended {
pub service_name: String,
pub endpoint_name: String,
pub metrics: Vec<MetricOutputExtended>,
}
impl PrometheusMetricsExtended {
pub async fn new_zvks(metrics: Vec<MetricOutputExtended>) -> Self {
Self {
service_name : "zvks".to_owned(),
endpoint_name : "apiforsnmp".to_owned(),
metrics : metrics,
}
}
pub fn get_bytes_len(&self) -> usize {
let str_metrics = serde_json::to_vec(self).unwrap_or_else(
|_| Vec::new()
);
str_metrics.len()
}
}
}
pub mod enode_monitoring {
use std::hash::Hash;
use super::*;
#[derive(Debug, Serialize)]
pub struct ForTokenCredentials {
login : String,
password : String,
pub ts : String,
}
impl ForTokenCredentials {
pub fn new(login: &str, pass: &str) -> Self {
Self {
login : login.to_owned(),
password : pass.to_owned(),
ts : format!("{}", DateTime::timestamp(&Local::now())),
}
}
}
pub mod cmdb {
use super::*;
#[derive(Debug, Serialize)]
pub struct Query {
id : Vec<String>,
data : Data,
#[serde(rename = "postQuery")]
post_query : String,
#[serde(rename = "enableActions")]
enable_actions : bool,
ts : usize
}
impl Default for Query {
fn default() -> Self {
Self {
id : vec!["/measures/device$18".to_owned()],
data : Data::default(),
post_query : "links".to_owned(),
enable_actions : false,
ts : 1740060679399
}
}
}
#[derive(Debug, Serialize)]
struct Data {
links : Links,
fields : Vec<String>,
}
impl Default for Data {
fn default() -> Self {
Self {
links : Links::default(),
fields : vec![ "$id".to_owned(), "id".to_owned(), "cls".to_owned(), "name".to_owned()]
}
}
}
#[derive(Debug, Serialize)]
struct Links {
flatten : bool,
filter : Filter,
}
impl Default for Links {
fn default() -> Self {
Self {
flatten : true,
filter : Filter::default()
}
}
}
#[derive(Debug, Serialize)]
struct Filter {
cls : String,
}
impl Default for Filter {
fn default() -> Self {
Self {
cls : "measure".to_owned()
}
}
}
}
#[derive(Debug, Deserialize)]
pub struct AuthResponse {
pub access_token : String,
// role : String,
// startRT : String,
// login : String,
// push_active : Value,
// #[serde(rename = "$id")]
// id : String,
}
pub trait GenericUrl {
fn display(&self) -> String;
}
pub trait LazyUnzip<K, V>
where
V : Clone,
K : Hash + Eq + Clone {
fn lazy_unzip(&self) -> HashMap<K, V>;
}
impl<T> GenericUrl for [(T, T)]
where T : Display {
fn display(&self) -> String {
let mut vec: Vec<String> = Vec::new();
vec.push("%5B".to_owned());
self.iter()
.enumerate()
.for_each(|(id, val)| {
if id > 0 {
vec.push(",".to_owned());
}
vec.push(format!("%22{}%22", val.0));
});
vec.push("%5D".to_owned());
vec.concat()
}
}
impl<K, V> LazyUnzip<K, V> for [(K, V)]
where
V : Clone,
K : Hash + Eq + Clone {
fn lazy_unzip(&self) -> HashMap<K, V> {
let mut hm = HashMap::new();
self.into_iter()
.for_each(|(key, val)| {hm.insert(key.to_owned(), val.to_owned());});
hm
}
}
pub fn get_chunk_size(total_measures: usize) -> usize {
match total_measures {
0..=144 => total_measures,
145..=288 => total_measures / 4,
289..=432 => total_measures / 5,
433..=576 => total_measures / 6,
577..=720 => total_measures / 7,
721..=864 => total_measures / 8,
865..=1008 => total_measures / 9,
_ => total_measures / 10,
}
}
}