From 41d2db1b63641d7d2cfc9db80e41e8437f6c96b3 Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Thu, 13 Jan 2022 13:53:26 -0500 Subject: [PATCH 1/2] feat: support station busyout/release toggling via extension Introduces bulk station busyout/release toggle endpoints via the `simple_busy` extension. Bumps `angelsharkd` version. Feature is documented in README. Removes TODO in `simple_deprov` README. --- Cargo.lock | 2 +- angelsharkd/Cargo.toml | 3 +- angelsharkd/src/routes/extensions/mod.rs | 8 ++ .../routes/extensions/simple_busy/README.md | 50 ++++++++++ .../src/routes/extensions/simple_busy/mod.rs | 98 +++++++++++++++++++ .../routes/extensions/simple_deprov/README.md | 2 +- 6 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 angelsharkd/src/routes/extensions/simple_busy/README.md create mode 100644 angelsharkd/src/routes/extensions/simple_busy/mod.rs diff --git a/Cargo.lock b/Cargo.lock index cd177a2..2120e3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,7 +24,7 @@ dependencies = [ [[package]] name = "angelsharkd" -version = "0.2.1" +version = "0.2.2" dependencies = [ "anyhow", "env_logger", diff --git a/angelsharkd/Cargo.toml b/angelsharkd/Cargo.toml index 0bb1294..62ffebb 100644 --- a/angelsharkd/Cargo.toml +++ b/angelsharkd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "angelsharkd" -version = "0.2.1" +version = "0.2.2" edition = "2021" authors = ["Adam T. Carpenter "] description = "A HTTP interface into one or more Communication Managers" @@ -8,6 +8,7 @@ description = "A HTTP interface into one or more Communication Managers" [features] simple_search = [] simple_deprov = [] +simple_busy = [] [dependencies.libangelshark] path = "../libangelshark" diff --git a/angelsharkd/src/routes/extensions/mod.rs b/angelsharkd/src/routes/extensions/mod.rs index 54053af..a775880 100644 --- a/angelsharkd/src/routes/extensions/mod.rs +++ b/angelsharkd/src/routes/extensions/mod.rs @@ -1,6 +1,8 @@ use crate::config::Config; use warp::{path, Filter, Rejection, Reply}; +#[cfg(feature = "simple_busy")] +mod simple_busy; #[cfg(feature = "simple_deprov")] mod simple_deprov; #[cfg(feature = "simple_search")] @@ -26,6 +28,12 @@ pub fn filter(config: &Config) -> impl Filter impl Filter + Clone { + post() + .and(path!("service" / "busyout" / ..)) + .and(content_length_limit(SIXTEEN_K)) + .and(json()) + .map(move |entries| queue_and_run(entries, "busyout", runner.to_owned())) +} + +pub fn release_filter( + runner: AcmRunner, +) -> impl Filter + Clone { + post() + .and(path!("service" / "release" / ..)) + .and(content_length_limit(SIXTEEN_K)) + .and(json()) + .map(move |entries| queue_and_run(entries, "release", runner.to_owned())) +} + +pub fn toggle_filter( + runner: AcmRunner, +) -> impl Filter + Clone { + post() + .and(path!("service" / "toggle" / ..)) + .and(content_length_limit(SIXTEEN_K)) + .and(json()) + .map(move |entries| queue_and_run(entries, "toggle", runner.to_owned())) +} + +fn queue_and_run(entries: Entries, command: &str, mut runner: AcmRunner) -> impl Reply { + for entry in entries.into_iter() { + if command == "toggle" { + runner.queue_input( + &entry.acm, + &Message::new(&format!("busyout station {}", entry.ext)), + ); + runner.queue_input( + &entry.acm, + &Message::new(&format!("release station {}", entry.ext)), + ); + } else { + runner.queue_input( + &entry.acm, + &Message::new(&format!("{} station {}", command, entry.ext)), + ); + } + } + + // generate output on runner + let output: Result>, _> = runner + .run() + .map(|(name, output)| -> Result, anyhow::Error> { + Ok(output? + .into_iter() + .filter_map(move |msg| { + (msg.command != "logoff").then(|| Response::from((name.to_owned(), msg))) + }) + .collect()) + }) + .collect(); + + // handle errors and package output as json + match output { + Err(e) => { + error!("busyout-release extension: {}", e); + reply::with_status( + reply::json(&Error { + reason: e.to_string(), + }), + StatusCode::INTERNAL_SERVER_ERROR, + ) + } + Ok(r) => reply::with_status( + reply::json(&r.into_iter().flatten().collect::>()), + StatusCode::OK, + ), + } +} + +type Entries = Vec; +#[derive(Debug, Deserialize)] +struct Entry { + acm: String, + ext: String, +} diff --git a/angelsharkd/src/routes/extensions/simple_deprov/README.md b/angelsharkd/src/routes/extensions/simple_deprov/README.md index 4900075..f7a3fe2 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov/README.md +++ b/angelsharkd/src/routes/extensions/simple_deprov/README.md @@ -16,7 +16,7 @@ cargo build --bin angelsharkd --features simple_deprov ... ## `POST /extensions/deprov` Remove Objects -The request type is TODO: +The request type is as follows: ```json POST /extensions/deprov From 579980ca75dfbc27639259c773dfc5fe1ec9e32a Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Mon, 17 Jan 2022 14:57:18 -0500 Subject: [PATCH 2/2] feat: log data for station being removed in simple_deprov --- .../src/routes/extensions/simple_deprov/mod.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/angelsharkd/src/routes/extensions/simple_deprov/mod.rs b/angelsharkd/src/routes/extensions/simple_deprov/mod.rs index fc734f3..77bde55 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov/mod.rs +++ b/angelsharkd/src/routes/extensions/simple_deprov/mod.rs @@ -1,5 +1,5 @@ use libangelshark::{AcmRunner, Message, ParallelIterator}; -use log::error; +use log::{error, info}; use serde::Deserialize; use std::convert::Infallible; use warp::{ @@ -24,10 +24,12 @@ async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result { + runner.queue_input(&acm, &Message::new(&format!("list station {}", ext))); runner.queue_input(&acm, &Message::new(&format!("clear amw all {}", ext))); runner.queue_input(&acm, &Message::new(&format!("remove station {}", ext))); } Entry::AgentLoginId { acm, ext } => { + runner.queue_input(&acm, &Message::new(&format!("list agent-loginID {}", ext))); runner.queue_input( &acm, &Message::new(&format!("remove agent-loginID {}", ext)), @@ -42,7 +44,16 @@ async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result messages .into_iter() - .filter_map(|message| Some(format!("ACM {}: {}", acm.clone(), message.error?))) + .filter_map(|message| { + if let Some(data) = message + .datas + .and_then(|d| Some(format!("{acm}\t{}", d.get(0)?.join("\t")))) + { + // if there was data (such as in lists), print it out + info!("{data}"); + } + Some(format!("ACM {}: {}", acm.clone(), message.error?)) + }) .collect(), Err(error) => vec![format!("ACM {}: {}", acm, error)], })