From 35c94460db7844da9803891701f9258dd7742814 Mon Sep 17 00:00:00 2001 From: "Crom (Thibaut CHARLES)" Date: Thu, 31 Jan 2019 11:01:47 +0100 Subject: [PATCH] Initial architecture --- Cargo.lock | 104 ++++++++++++++++++++++++++++ Cargo.toml | 6 +- config.yaml | 6 ++ src/config.rs | 8 +++ src/main.rs | 125 ++++++++++++++++++++++++---------- src/message.rs | 24 ++----- src/monitor.rs | 10 +-- src/output.rs | 12 ++-- src/plugins/mod.rs | 2 +- src/plugins/monitor/mod.rs | 2 +- src/plugins/monitor/tester.rs | 42 ++++++------ src/plugins/output/mod.rs | 2 +- src/plugins/output/stdout.rs | 24 +++---- 13 files changed, 260 insertions(+), 107 deletions(-) create mode 100644 config.yaml create mode 100644 src/config.rs diff --git a/Cargo.lock b/Cargo.lock index a52e38b..3d05df3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,6 +3,19 @@ name = "cc" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "dtoa" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "getopts" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "libloading" version = "0.5.0" @@ -12,13 +25,84 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "linked-hash-map" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rnetmon" version = "0.1.0" dependencies = [ + "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_yaml" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.3.6" @@ -38,9 +122,29 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "yaml-rust" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" +"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" +"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" +"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" +"checksum proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "38fddd23d98b2144d197c0eca5705632d4fe2667d14a6be5df8934f8d74f1978" +"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" +"checksum serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "534b8b91a95e0f71bca3ed5824752d558da048d4248c91af873b63bd60519752" +"checksum serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "a915306b0f1ac5607797697148c223bedeaa36bcc2e28a01441cd638cc6567b4" +"checksum serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0887a8e097a69559b56aa2526bf7aff7c3048cf627dff781f0b56a6001534593" +"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e" diff --git a/Cargo.toml b/Cargo.toml index ce27939..562867e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,8 @@ authors = ["Thibaut CHARLES"] edition = "2018" [dependencies] -libloading = "0.5.0" \ No newline at end of file +libloading = "0.5.0" +serde = "1.0" +serde_yaml = "0.8" +serde_derive = "1.0" +getopts = "0.2" \ No newline at end of file diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..598509e --- /dev/null +++ b/config.yaml @@ -0,0 +1,6 @@ +monitors: + - name: tester + - name: tester + +outputs: + - name: stdout \ No newline at end of file diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..7ba3ace --- /dev/null +++ b/src/config.rs @@ -0,0 +1,8 @@ +use serde_derive::*; +use std::collections::HashMap; + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct Config { + pub monitors: Vec>, + pub outputs: Vec>, +} diff --git a/src/main.rs b/src/main.rs index c745b11..e9fcb7d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,63 +1,115 @@ +mod config; mod message; mod monitor; mod output; mod plugins; -use std::thread; +extern crate getopts; +extern crate serde_derive; +extern crate serde_yaml; + +use std::env; +use std::fs::File; +use std::io::prelude::*; use std::sync::mpsc; +use std::thread; -use crate::monitor::Monitor; -use crate::output::Output; -use crate::message::Message; +use getopts::Options; +use crate::config::*; +use crate::message::*; +use crate::monitor::*; +use crate::output::*; + +fn monitor_factory(name: &str, config: &HashMap) -> Box { + match name { + "tester" => Box::new(plugins::monitor::tester::Tester::new(&config)), + _ => panic!("Unknown monitor name: {}", name), + } +} + +fn output_factory(name: &str, config: &HashMap) -> Box { + match name { + "stdout" => Box::new(plugins::output::stdout::Stdout::new(&config)), + _ => panic!("Unknown monitor name: {}", name), + } +} fn main() { - // let lib = Library::new("/home/crom/.gitprojects/rnetmon/plugins/output/stdout/target/debug/deps/libstdout.so").unwrap(); + let args: Vec = env::args().collect(); - // unsafe { - // let handle_message: Symbol = lib.get(b"handle_message").unwrap(); - // handle_message(); - // } - // let msg = Message{ - // emitter: "me".to_string(), - // level: 10, - // msg_type: "string".to_string(), - // text: "Consectetur duis do dolor deserunt est minim dolore tempor et non duis.".to_string(), - // }; + // Parse command line args + let mut opts = Options::new(); + opts.optopt( + "c", + "config", + "Path to config.yaml. Default: ./config.yaml", + "config.yaml", + ); + opts.optflag("h", "help", "print this help menu"); + + let matches = match opts.parse(&args[1..]) { + Ok(m) => m, + Err(f) => panic!(f.to_string()), + }; + if matches.opt_present("h") { + let brief = format!("Usage: {} [options]", args[0]); + print!("{}", opts.usage(&brief)); + return; + } + + // Parse config + let config_path = matches.opt_str("c").unwrap_or("./config.yaml".to_string()); + let mut config_file = File::open(config_path).expect("Could not open configuration file"); + let mut config_content = String::new(); + config_file + .read_to_string(&mut config_content) + .expect("Could not read configuration file"); + let config: Config = + serde_yaml::from_str(&config_content).expect("Invalid config file content"); + + // Monitors -> dispatcher channel let (mon_sender, mon_receiver) = mpsc::channel(); - // let mut monitors: Vec<(Box, thread::JoinHandle<_>)> = vec![]; - let mut monitor_threads: Vec> = vec![]; - { + // Instantiate monitor threads and structs + for mon_config in config.monitors { + let name = mon_config + .get("name") + .expect("Missing `name` key for monitor") + .as_str() + .expect("Key `name` for monitor is not a string"); + + println!("Loading monitor: {}", name); + let snd = mon_sender.clone(); - let mon = plugins::monitor::tester::Tester::new(); - let thread = thread::spawn(move|| { - loop { - mon.run(&snd); - } + let mut mon = monitor_factory(name, &mon_config); + thread::spawn(move || loop { + mon.run(&snd); }); - monitor_threads.push(thread) - // monitor_threads.push((mon, thread)); } - let monitor_threads = monitor_threads; - + // Instantiate output threads and structs let mut output_senders: Vec> = vec![]; - let mut output_threads: Vec> = vec![]; - { + for out_config in config.outputs { + let name = out_config + .get("name") + .expect("Missing `name` key for monitor") + .as_str() + .expect("Key `name` for monitor is not a string"); + + println!("Loading output: {}", name); + let (out_sender, out_receiver) = mpsc::channel(); output_senders.push(out_sender); - let thread = thread::spawn(move|| { - loop { - let message = out_receiver.recv().unwrap(); - println!("{:?}", message); - } + let mut output = output_factory(name, &out_config); + + thread::spawn(move || loop { + let message = out_receiver.recv().unwrap(); + output.process_message(message); }); - output_threads.push(thread); } let output_senders = output_senders; - let output_threads = output_threads; // Dispatch messages loop { @@ -66,5 +118,4 @@ fn main() { out.send(message.clone()).unwrap(); } } - } diff --git a/src/message.rs b/src/message.rs index 9b6bfd6..accee1a 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,21 +1,7 @@ - - -#[derive(Debug)] -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct Message { - pub emitter: String, - pub level: i32, - pub msg_type: String, - pub text: String, + pub emitter: String, + pub level: i32, + pub msg_type: String, + pub text: String, } - -// impl Clone for Message { -// fn clone(&self) -> Self { -// Message{ -// emitter: self.emitter.clone(), -// level: self.level, -// msg_type: self.msg_type.clone(), -// text: self.text.clone(), -// } -// } -// } \ No newline at end of file diff --git a/src/monitor.rs b/src/monitor.rs index 8641905..9f06a41 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -1,9 +1,11 @@ - use crate::message::Message; +pub use std::collections::HashMap; pub use std::sync::mpsc; pub trait Monitor { - fn new() -> Self where Self: Sized; - fn run(&self, sender: &mpsc::Sender); -} \ No newline at end of file + fn new(config: &HashMap) -> Self + where + Self: Sized; + fn run(&mut self, sender: &mpsc::Sender); +} diff --git a/src/output.rs b/src/output.rs index 08ea0d9..9c53b11 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,8 +1,10 @@ - use crate::message::Message; -use std::sync::mpsc; + +pub use std::collections::HashMap; pub trait Output { - fn new(receiver: mpsc::Receiver) -> Self; - fn on_message(&self, message: Message); -} \ No newline at end of file + fn new(config: &HashMap) -> Self + where + Self: Sized; + fn process_message(&mut self, message: Message); +} diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index ce44066..69bcf7a 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,2 +1,2 @@ +pub mod monitor; pub mod output; -pub mod monitor; \ No newline at end of file diff --git a/src/plugins/monitor/mod.rs b/src/plugins/monitor/mod.rs index 63da92c..918dcc7 100644 --- a/src/plugins/monitor/mod.rs +++ b/src/plugins/monitor/mod.rs @@ -1 +1 @@ -pub mod tester; \ No newline at end of file +pub mod tester; diff --git a/src/plugins/monitor/tester.rs b/src/plugins/monitor/tester.rs index 1893c14..26a8142 100644 --- a/src/plugins/monitor/tester.rs +++ b/src/plugins/monitor/tester.rs @@ -1,31 +1,27 @@ - -pub use crate::monitor::Monitor; pub use crate::message::Message; -pub use std::sync::mpsc; - +pub use crate::monitor::*; #[derive(Debug)] pub struct Tester { - + cnt: i64, } impl Monitor for Tester { - fn new() -> Self { - Tester{} - } - fn run(&self, sender: &mpsc::Sender) { + fn new(config: &HashMap) -> Self { + Tester { cnt: 0 } + } + fn run(&mut self, sender: &mpsc::Sender) { + println!("-- Sending message {}", self.cnt); + sender + .send(Message { + emitter: "me".to_string(), + level: 10, + msg_type: "string".to_string(), + text: format!("This is message number {}", self.cnt), + }) + .unwrap(); - loop { - println!("-- Sending message"); - sender.send(Message{ - emitter: "me".to_string(), - level: 10, - msg_type: "string".to_string(), - text: "Consectetur duis do dolor deserunt est minim dolore tempor et non duis.".to_string(), - }).unwrap(); - - std::thread::sleep(std::time::Duration::from_millis(2000)); - } - - } -} \ No newline at end of file + self.cnt += 1; + std::thread::sleep(std::time::Duration::from_millis(2000)); + } +} diff --git a/src/plugins/output/mod.rs b/src/plugins/output/mod.rs index d54cf68..76c718c 100644 --- a/src/plugins/output/mod.rs +++ b/src/plugins/output/mod.rs @@ -1 +1 @@ -pub mod stdout; \ No newline at end of file +pub mod stdout; diff --git a/src/plugins/output/stdout.rs b/src/plugins/output/stdout.rs index f18e324..8df8ce5 100644 --- a/src/plugins/output/stdout.rs +++ b/src/plugins/output/stdout.rs @@ -1,20 +1,14 @@ - use crate::message::Message; -pub use crate::output::Output; -use std::sync::mpsc; +pub use crate::output::*; #[derive(Debug)] -pub struct Stdout { - receiver: mpsc::Receiver, -} +pub struct Stdout {} impl Output for Stdout { - fn new(receiver: mpsc::Receiver) -> Self { - Stdout{ - receiver: receiver - } - } - fn on_message(&self, message: Message){ - - } -} \ No newline at end of file + fn new(config: &HashMap) -> Self { + Stdout {} + } + fn process_message(&mut self, message: Message) { + println!("Received message: {:?}", message); + } +}