Initial architecture

This commit is contained in:
Crom (Thibaut CHARLES) 2019-01-31 11:01:47 +01:00
parent 140a094b15
commit 35c94460db
Signed by: tcharles
GPG Key ID: 45A3D5F880B9E6D0
13 changed files with 260 additions and 107 deletions

104
Cargo.lock generated
View File

@ -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"

View File

@ -5,4 +5,8 @@ authors = ["Thibaut CHARLES"]
edition = "2018"
[dependencies]
libloading = "0.5.0"
libloading = "0.5.0"
serde = "1.0"
serde_yaml = "0.8"
serde_derive = "1.0"
getopts = "0.2"

6
config.yaml Normal file
View File

@ -0,0 +1,6 @@
monitors:
- name: tester
- name: tester
outputs:
- name: stdout

8
src/config.rs Normal file
View File

@ -0,0 +1,8 @@
use serde_derive::*;
use std::collections::HashMap;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Config {
pub monitors: Vec<HashMap<String, serde_yaml::Value>>,
pub outputs: Vec<HashMap<String, serde_yaml::Value>>,
}

View File

@ -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<String, serde_yaml::Value>) -> Box<Monitor + Send> {
match name {
"tester" => Box::new(plugins::monitor::tester::Tester::new(&config)),
_ => panic!("Unknown monitor name: {}", name),
}
}
fn output_factory(name: &str, config: &HashMap<String, serde_yaml::Value>) -> Box<Output + Send> {
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<String> = env::args().collect();
// unsafe {
// let handle_message: Symbol<unsafe fn()> = 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<Monitor>, thread::JoinHandle<_>)> = vec![];
let mut monitor_threads: Vec<thread::JoinHandle<_>> = 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<mpsc::Sender<Message>> = vec![];
let mut output_threads: Vec<thread::JoinHandle<_>> = 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();
}
}
}

View File

@ -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(),
// }
// }
// }

View File

@ -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<Message>);
}
fn new(config: &HashMap<String, serde_yaml::Value>) -> Self
where
Self: Sized;
fn run(&mut self, sender: &mpsc::Sender<Message>);
}

View File

@ -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<Message>) -> Self;
fn on_message(&self, message: Message);
}
fn new(config: &HashMap<String, serde_yaml::Value>) -> Self
where
Self: Sized;
fn process_message(&mut self, message: Message);
}

View File

@ -1,2 +1,2 @@
pub mod monitor;
pub mod output;
pub mod monitor;

View File

@ -1 +1 @@
pub mod tester;
pub mod tester;

View File

@ -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<Message>) {
fn new(config: &HashMap<String, serde_yaml::Value>) -> Self {
Tester { cnt: 0 }
}
fn run(&mut self, sender: &mpsc::Sender<Message>) {
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));
}
}
}
self.cnt += 1;
std::thread::sleep(std::time::Duration::from_millis(2000));
}
}

View File

@ -1 +1 @@
pub mod stdout;
pub mod stdout;

View File

@ -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<Message>,
}
pub struct Stdout {}
impl Output for Stdout {
fn new(receiver: mpsc::Receiver<Message>) -> Self {
Stdout{
receiver: receiver
}
}
fn on_message(&self, message: Message){
}
}
fn new(config: &HashMap<String, serde_yaml::Value>) -> Self {
Stdout {}
}
fn process_message(&mut self, message: Message) {
println!("Received message: {:?}", message);
}
}