Compare commits
71 Commits
detection_
...
main
Author | SHA1 | Date |
---|---|---|
rozetko | 77c5d3d3ce | 2 years ago |
rozetko | d099998562 | 2 years ago |
rozetko | abbadbc155 | 2 years ago |
rozetko | fce0f30e9e | 2 years ago |
rozetko | f4226a5245 | 2 years ago |
rozetko | 57854909f9 | 2 years ago |
rozetko | e16410d407 | 2 years ago |
Alexey Velikiy | 5f16e006a8 | 2 years ago |
Alexey Velikiy | 55c0fca371 | 2 years ago |
glitch4347 | aa4008662a | 2 years ago |
Alexey Velikiy | a9d2995281 | 2 years ago |
glitch4347 | eee437d779 | 2 years ago |
Alexey Velikiy | b7fb951590 | 2 years ago |
Alexey Velikiy | ad95c1e49f | 2 years ago |
glitch4347 | f684d8ee6a | 2 years ago |
Alexey Velikiy | 0d756d3f42 | 2 years ago |
Alexey Velikiy | a4da3b5ea3 | 2 years ago |
Alexey Velikiy | cafb50cce3 | 2 years ago |
Alexey Velikiy | c7284f4305 | 2 years ago |
glitch4347 | cb87a98e39 | 2 years ago |
glitch4347 | 49c2e30acc | 2 years ago |
rozetko | 8e4b29508b | 2 years ago |
rozetko | ed28530955 | 2 years ago |
rusdacent | e0e4d93ebb | 2 years ago |
rusdacent | 8121292450 | 2 years ago |
rusdacent | 2d5786d639 | 2 years ago |
rusdacent | 0733a5d002 | 2 years ago |
rusdacent | e20a5affcc | 2 years ago |
glitch4347 | 545c932f6b | 2 years ago |
rozetko | 936d207a74 | 2 years ago |
rozetko | 4ed8ba1193 | 2 years ago |
rozetko | 70c49fe91b | 2 years ago |
glitch4347 | 052e5a5987 | 2 years ago |
glitch4347 | 8ab0718326 | 2 years ago |
glitch4347 | 4f66b59b7e | 2 years ago |
rozetko | 7d190c426a | 2 years ago |
glitch4347 | 637eef2105 | 2 years ago |
Alexey Velikiy | 7731e2f56b | 2 years ago |
Alexey Velikiy | 6b44428586 | 2 years ago |
Alexey Velikiy | 6f6f946b5b | 2 years ago |
glitch4347 | 278ea473f2 | 2 years ago |
Alexey Velikiy | 81069e9782 | 2 years ago |
Alexey Velikiy | 21f4b6eaaa | 2 years ago |
Alexey Velikiy | a200e3d450 | 2 years ago |
Alexey Velikiy | d7b283f1ff | 2 years ago |
Alexey Velikiy | 1af18e1118 | 2 years ago |
Alexey Velikiy | df3be270b8 | 2 years ago |
glitch4347 | f1d31b9637 | 2 years ago |
glitch4347 | 2498c40bed | 2 years ago |
Alexey Velikiy | b5f960a6ea | 2 years ago |
Alexey Velikiy | 3313a92039 | 2 years ago |
Alexey Velikiy | a982f8f1f5 | 2 years ago |
Alexey Velikiy | 1f2d6f551e | 2 years ago |
Alexey Velikiy | 5bf13b171b | 2 years ago |
Alexey Velikiy | 090b9bf42e | 2 years ago |
Alexey Velikiy | 86a1f7e3a6 | 2 years ago |
Alexey Velikiy | b26d36fad2 | 2 years ago |
Alexey Velikiy | 4b6e95e784 | 2 years ago |
glitch4347 | 5fa9cf8ba2 | 2 years ago |
rozetko | ef572afcaa | 2 years ago |
rozetko | 4774f5d6b5 | 2 years ago |
Alexey Velikiy | 311e5a8041 | 2 years ago |
Alexey Velikiy | 1565c156e0 | 2 years ago |
Alexey Velikiy | d23af0482b | 2 years ago |
Alexey Velikiy | 187ec15f1b | 2 years ago |
glitch4347 | 0eff1204f2 | 2 years ago |
Alexey Velikiy | c79993bc52 | 2 years ago |
Alexey Velikiy | a338b3339b | 2 years ago |
Alexey Velikiy | 9904e4d449 | 2 years ago |
Alexey Velikiy | 0761e4d9b2 | 2 years ago |
glitch4347 | 1b89075ad0 | 2 years ago |
24 changed files with 627 additions and 164 deletions
@ -0,0 +1,27 @@
|
||||
FROM rust:1.57.0-bullseye as builder |
||||
|
||||
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - |
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ |
||||
nodejs \ |
||||
gcc \ |
||||
g++ \ |
||||
make \ |
||||
musl-tools \ |
||||
&& rm -rf /var/lib/apt/lists/* |
||||
|
||||
RUN npm install --global yarn |
||||
|
||||
RUN rustup target add x86_64-unknown-linux-musl |
||||
|
||||
ADD . ./ |
||||
|
||||
RUN make |
||||
|
||||
FROM debian:bullseye-slim |
||||
|
||||
COPY --from=builder /release/hastic /hastic |
||||
COPY --from=builder /release/config.toml /config.toml |
||||
COPY --from=builder /release/public /public |
||||
|
||||
CMD ["./hastic"] |
@ -0,0 +1,12 @@
|
||||
|
||||
version: '3' |
||||
services: |
||||
app: |
||||
image: hastic/hastic:latest |
||||
restart: always |
||||
environment: |
||||
HASTIC_PORT: "4347" |
||||
HASTIC_PROMETHEUS__URL: "http://demo.robustperception.io:9090" |
||||
HASTIC_PROMETHEUS__QUERY: "rate(go_memstats_alloc_bytes_total[1m])" |
||||
ports: |
||||
- "4347:4347" |
@ -1,76 +1,195 @@
|
||||
use std::sync::{Arc, Mutex}; |
||||
|
||||
use crate::utils::get_random_str; |
||||
use rusqlite::{params, Connection}; |
||||
|
||||
use rusqlite::{params, Connection, Row}; |
||||
use warp::hyper::rt::Executor; |
||||
use super::analytic_service::analytic_unit::{ |
||||
anomaly_analytic_unit::AnomalyAnalyticUnit, |
||||
pattern_analytic_unit::PatternAnalyticUnit, |
||||
threshold_analytic_unit::ThresholdAnalyticUnit, |
||||
types::{self, AnalyticUnitConfig}, |
||||
}; |
||||
|
||||
use super::analytic_service::analytic_unit::{types::{AnalyticUnitConfig, self}, threshold_analytic_unit::ThresholdAnalyticUnit, pattern_analytic_unit::PatternAnalyticUnit, anomaly_analytic_unit::AnomalyAnalyticUnit}; |
||||
use super::data_service::DataService; |
||||
|
||||
#[derive(Clone)] |
||||
pub struct AnalyticUnitService { |
||||
// TODO: resolve by setting id for 3 types
|
||||
// TODO: create database
|
||||
// TODO: update detection
|
||||
connection: Arc<Mutex<Connection>> |
||||
connection: Arc<Mutex<Connection>>, |
||||
} |
||||
|
||||
// TODO: get DataService
|
||||
impl AnalyticUnitService { |
||||
pub fn new() -> anyhow::Result<AnalyticUnitService> { |
||||
// TODO: remove repetitoin with segment_service
|
||||
std::fs::create_dir_all("./data").unwrap(); |
||||
let conn = Connection::open("./data/analytic_units.db")?; |
||||
pub fn new(ds: &DataService) -> anyhow::Result<AnalyticUnitService> { |
||||
let conn = ds.analytic_units_connection.clone(); |
||||
|
||||
// TODO: add learning results field
|
||||
conn.execute( |
||||
conn.lock().unwrap().execute( |
||||
"CREATE TABLE IF NOT EXISTS analytic_unit ( |
||||
id TEXT PRIMARY KEY, |
||||
last_detection INTEGER |
||||
last_detection INTEGER, |
||||
active BOOLEAN, |
||||
type INTEGER, |
||||
config TEXT |
||||
)", |
||||
[], |
||||
)?; |
||||
|
||||
Ok(AnalyticUnitService { |
||||
connection: Arc::new(Mutex::new(conn)), |
||||
connection: conn |
||||
}) |
||||
} |
||||
|
||||
// TODO: optional id
|
||||
pub fn resolve_au(&self, cfg: AnalyticUnitConfig) -> Box<dyn types::AnalyticUnit + Send + Sync> { |
||||
pub fn resolve_au( |
||||
&self, |
||||
cfg: &AnalyticUnitConfig, |
||||
) -> Box<dyn types::AnalyticUnit + Send + Sync> { |
||||
match cfg { |
||||
AnalyticUnitConfig::Threshold(c) => Box::new(ThresholdAnalyticUnit::new("1".to_string(), c.clone())), |
||||
AnalyticUnitConfig::Pattern(c) => Box::new(PatternAnalyticUnit::new("2".to_string(), c.clone())), |
||||
AnalyticUnitConfig::Anomaly(c) => Box::new(AnomalyAnalyticUnit::new("3".to_string(), c.clone())), |
||||
AnalyticUnitConfig::Threshold(c) => { |
||||
Box::new(ThresholdAnalyticUnit::new("1".to_string(), c.clone())) |
||||
} |
||||
AnalyticUnitConfig::Pattern(c) => { |
||||
Box::new(PatternAnalyticUnit::new("2".to_string(), c.clone())) |
||||
} |
||||
AnalyticUnitConfig::Anomaly(c) => { |
||||
Box::new(AnomalyAnalyticUnit::new("3".to_string(), c.clone())) |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub fn resolve(&self, cfg: AnalyticUnitConfig) -> anyhow::Result<Box<dyn types::AnalyticUnit + Send + Sync>> { |
||||
// TODO: get id of analytic_unit which be used also as it's type
|
||||
pub fn resolve( |
||||
&self, |
||||
cfg: &AnalyticUnitConfig, |
||||
) -> anyhow::Result<Box<dyn types::AnalyticUnit + Send + Sync>> { |
||||
let au = self.resolve_au(cfg); |
||||
let id = au.as_ref().get_id(); |
||||
|
||||
let conn = self.connection.lock().unwrap(); |
||||
let mut stmt = conn.prepare( |
||||
"SELECT id from analytic_unit WHERE id = ?1", |
||||
)?; |
||||
let mut stmt = conn.prepare("SELECT id from analytic_unit WHERE id = ?1")?; |
||||
let res = stmt.exists(params![id])?; |
||||
|
||||
if res == false { |
||||
let cfg_json = serde_json::to_string(&cfg)?; |
||||
conn.execute( |
||||
"INSERT INTO analytic_unit (id) VALUES (?1)", |
||||
params![id] |
||||
"INSERT INTO analytic_unit (id, type, config) VALUES (?1, ?1, ?2)", |
||||
params![id, cfg_json], |
||||
)?; |
||||
} |
||||
|
||||
conn.execute( |
||||
"UPDATE analytic_unit set active = FALSE where active = TRUE", |
||||
params![], |
||||
)?; |
||||
conn.execute( |
||||
"UPDATE analytic_unit set active = TRUE where id = ?1", |
||||
params![id], |
||||
)?; |
||||
|
||||
return Ok(au); |
||||
} |
||||
|
||||
// TODO: resolve with saving by id
|
||||
pub fn set_last_detection(&self, id: String, last_detection: u64) -> anyhow::Result<()> { |
||||
let conn = self.connection.lock().unwrap(); |
||||
conn.execute( |
||||
"UPDATE analytic_unit SET last_detection = ?1 WHERE id = ?2", |
||||
params![last_detection, id] |
||||
params![last_detection, id], |
||||
)?; |
||||
Ok(()) |
||||
} |
||||
} |
||||
|
||||
pub fn get_active(&self) -> anyhow::Result<Box<dyn types::AnalyticUnit + Send + Sync>> { |
||||
// TODO: return default when there is no active
|
||||
let conn = self.connection.lock().unwrap(); |
||||
let mut stmt = |
||||
conn.prepare("SELECT id, type, config from analytic_unit WHERE active = TRUE")?; |
||||
|
||||
let au = stmt.query_row([], |row| { |
||||
let c: String = row.get(2)?; |
||||
let cfg: AnalyticUnitConfig = serde_json::from_str(&c).unwrap(); |
||||
Ok(self.resolve(&cfg)) |
||||
})??; |
||||
|
||||
return Ok(au); |
||||
} |
||||
|
||||
pub fn get_active_config(&self) -> anyhow::Result<AnalyticUnitConfig> { |
||||
let exists = { |
||||
let conn = self.connection.lock().unwrap(); |
||||
let mut stmt = conn.prepare("SELECT config from analytic_unit WHERE active = TRUE")?; |
||||
stmt.exists([])? |
||||
}; |
||||
|
||||
if exists == false { |
||||
let c = AnalyticUnitConfig::Pattern(Default::default()); |
||||
self.resolve(&c)?; |
||||
return Ok(c); |
||||
} else { |
||||
let conn = self.connection.lock().unwrap(); |
||||
let mut stmt = conn.prepare("SELECT config from analytic_unit WHERE active = TRUE")?; |
||||
let acfg = stmt.query_row([], |row| { |
||||
let c: String = row.get(0)?; |
||||
let cfg = serde_json::from_str(&c).unwrap(); |
||||
Ok(cfg) |
||||
})?; |
||||
return Ok(acfg); |
||||
} |
||||
} |
||||
|
||||
pub fn get_config_by_id(&self, id: &String) -> anyhow::Result<AnalyticUnitConfig> { |
||||
let exists = { |
||||
let conn = self.connection.lock().unwrap(); |
||||
let mut stmt = conn.prepare("SELECT config from analytic_unit WHERE id = ?1")?; |
||||
stmt.exists([id])? |
||||
}; |
||||
|
||||
if exists == false { |
||||
let c = AnalyticUnitConfig::get_default_by_id(id); |
||||
self.resolve(&c)?; |
||||
return Ok(c); |
||||
} else { |
||||
let conn = self.connection.lock().unwrap(); |
||||
let mut stmt = conn.prepare("SELECT config from analytic_unit WHERE id = ?1")?; |
||||
let acfg = stmt.query_row([id], |row| { |
||||
let c: String = row.get(0)?; |
||||
let cfg = serde_json::from_str(&c).unwrap(); |
||||
Ok(cfg) |
||||
})?; |
||||
return Ok(acfg); |
||||
} |
||||
} |
||||
|
||||
pub fn get_config_id(&self, cfg: &AnalyticUnitConfig) -> String { |
||||
match cfg { |
||||
AnalyticUnitConfig::Threshold(_) => "1".to_string(), |
||||
AnalyticUnitConfig::Pattern(_) => "2".to_string(), |
||||
AnalyticUnitConfig::Anomaly(_) => "3".to_string(), |
||||
} |
||||
} |
||||
|
||||
pub fn update_config_by_id(&self, id: &String, cfg: &AnalyticUnitConfig) -> anyhow::Result<()> { |
||||
// TODO: it's possble that config doesn't exist, but we trying to update it
|
||||
let conn = self.connection.lock().unwrap(); |
||||
|
||||
let cfg_json = serde_json::to_string(&cfg)?; |
||||
|
||||
conn.execute( |
||||
"UPDATE analytic_unit SET config = ?1 WHERE id = ?2", |
||||
params![cfg_json, id], |
||||
)?; |
||||
|
||||
return Ok(()); |
||||
} |
||||
|
||||
pub fn update_active_config(&self, cfg: &AnalyticUnitConfig) -> anyhow::Result<()> { |
||||
let conn = self.connection.lock().unwrap(); |
||||
|
||||
let cfg_json = serde_json::to_string(&cfg)?; |
||||
|
||||
conn.execute( |
||||
"UPDATE analytic_unit SET config = ?1 WHERE active = TRUE", |
||||
params![cfg_json], |
||||
)?; |
||||
|
||||
return Ok(()); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,23 @@
|
||||
use std::sync::{Arc, Mutex}; |
||||
|
||||
use rusqlite::{Connection}; |
||||
|
||||
|
||||
pub struct DataService { |
||||
pub analytic_units_connection: Arc<Mutex<Connection>>, |
||||
pub segments_connection: Arc<Mutex<Connection>> |
||||
} |
||||
|
||||
impl DataService { |
||||
pub fn new() -> anyhow::Result<DataService> { |
||||
std::fs::create_dir_all("./data").unwrap(); |
||||
|
||||
let analytic_units_connection = Connection::open("./data/analytic_units.db")?; |
||||
let segments_connection = Connection::open("./data/segments.db")?; |
||||
|
||||
Ok(DataService { |
||||
analytic_units_connection: Arc::new(Mutex::new(analytic_units_connection)), |
||||
segments_connection: Arc::new(Mutex::new(segments_connection)) |
||||
}) |
||||
} |
||||
} |
Loading…
Reference in new issue