diff options
| author | Adam Carpenter <adam.carpenter@adp.com> | 2022-01-17 15:02:00 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-17 15:02:00 -0500 | 
| commit | 6e307700a5203f5b9fcc741f693fcacc7757414d (patch) | |
| tree | fe7781e07a74e05a82ea3c1e19c389337fe8ac8c /angelsharkd/src/routes/extensions/simple_busy | |
| parent | d3e1b697fec543e0197f1c549164c210504dde3b (diff) | |
| parent | 579980ca75dfbc27639259c773dfc5fe1ec9e32a (diff) | |
| download | altruistic-angelshark-6e307700a5203f5b9fcc741f693fcacc7757414d.tar.xz altruistic-angelshark-6e307700a5203f5b9fcc741f693fcacc7757414d.zip | |
feat: support station busyout/release toggling via extension
Diffstat (limited to 'angelsharkd/src/routes/extensions/simple_busy')
| -rw-r--r-- | angelsharkd/src/routes/extensions/simple_busy/README.md | 50 | ||||
| -rw-r--r-- | angelsharkd/src/routes/extensions/simple_busy/mod.rs | 98 | 
2 files changed, 148 insertions, 0 deletions
| diff --git a/angelsharkd/src/routes/extensions/simple_busy/README.md b/angelsharkd/src/routes/extensions/simple_busy/README.md new file mode 100644 index 0000000..dd9ba2c --- /dev/null +++ b/angelsharkd/src/routes/extensions/simple_busy/README.md @@ -0,0 +1,50 @@ +# Daemon Extension `simple_busy` + +This extension implements simple extension busyout and release toggling. + +## Getting Started + +To enable this feature, compile `angelsharkd` with the `simple_busy` flag: + +```sh +cargo build --bin angelsharkd --features simple_busy ... +``` + +## `POST /extensions/service/busyout` Busy-out a station + +The request consists of one or more entries including the ACM and extension to +be operated on. + +```json +POST /extensions/service/toggle +[ +    { +        "acm": "01", +        "ext": "17571230000" +    } +] +``` + +The response is a typical `angelsharkd` OSSI reponse. + +```json +[ +  { +    "acm": "01", +    "command": "busyout station 17571230000", +    "error": "", +    "fields": ["0001ff00", "0002ff00", "0005ff00", "0003ff00", "0004ff00"], +    "datas": [["S075157", "DIG-IP-S", "17571230000", "ABORT", "1010"]] +  } +] +``` + +## `POST /extensions/service/release` Release a station + +This endpoint works identically to the busyout endpoint, but the response will +indicate whether the station was released. + +## `POST /extensions/service/toggle` Busyout and then immediately release a station + +This endpoint runs two OSSI commands for busyout-ing and releasing the given +stations, respectively. diff --git a/angelsharkd/src/routes/extensions/simple_busy/mod.rs b/angelsharkd/src/routes/extensions/simple_busy/mod.rs new file mode 100644 index 0000000..23f05fd --- /dev/null +++ b/angelsharkd/src/routes/extensions/simple_busy/mod.rs @@ -0,0 +1,98 @@ +use crate::routes::dtos::{Error, Response}; +use libangelshark::{AcmRunner, Message, ParallelIterator}; +use log::error; +use serde::Deserialize; +use warp::{ +    body::{content_length_limit, json}, +    hyper::StatusCode, +    path, post, reply, Filter, Rejection, Reply, +}; + +const SIXTEEN_K: u64 = 1024 * 16; + +pub fn busy_filter( +    runner: AcmRunner, +) -> impl Filter<Extract = impl Reply, Error = Rejection> + 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<Extract = impl Reply, Error = Rejection> + 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<Extract = impl Reply, Error = Rejection> + 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<Vec<Vec<_>>, _> = runner +        .run() +        .map(|(name, output)| -> Result<Vec<Response>, 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::<Vec<_>>()), +            StatusCode::OK, +        ), +    } +} + +type Entries = Vec<Entry>; +#[derive(Debug, Deserialize)] +struct Entry { +    acm: String, +    ext: String, +} |