feat(old_device_sensor_api): initial work

This commit is contained in:
nm17 2024-03-06 23:14:29 +04:00
parent f909cbbdd3
commit e367930505
Signed by: nm17
GPG key ID: 3303B70C59145CD4
5 changed files with 116 additions and 67 deletions

View file

@ -11,3 +11,6 @@
- Поля
- `value`
- `unit`
- `devices_{device_id}`
- Поля
- `exists`: bool

View file

@ -12,7 +12,7 @@ use thiserror::Error;
use crate::insert_header;
use crate::web_server::old_devices_api::QSParserError;
use crate::web_server::old_device_sensor_api::QSParserError;
use rust_decimal::Decimal;
use serde_json::json;

View file

@ -6,7 +6,7 @@ use fred::prelude::*;
pub(crate) mod app_error;
pub mod old_app_api;
mod old_devices_api;
mod old_device_sensor_api;
pub mod utils;
#[derive(Clone)]
@ -14,7 +14,7 @@ pub struct NMAppState {
pub redis_client: RedisClient,
}
use crate::web_server::old_devices_api::device_handler;
use crate::web_server::old_device_sensor_api::device_handler;
use ntex::web;

View file

@ -0,0 +1,105 @@
mod qs_parser;
use std::str::FromStr;
use crate::ingest_protocol::{NMDeviceDataPacket, NMJsonPacket};
use crate::web_server::app_error::AppError;
use ntex::http::{HttpMessage, StatusCode};
use ntex::util::{Bytes, HashMap};
use ntex::{http, web};
use fred::prelude::*;
use hifitime::Epoch;
use thiserror::Error;
use ufmt::uwrite;
use crate::web_server::NMAppState;
#[derive(Error, Debug)]
pub enum Error {
#[error("Device not found")]
DeviceNotFound(String),
#[error("Time sent with the device is way to behind now")]
TimeIsLongBehindNow,
}
pub async fn device_handler<'a>(
request: web::HttpRequest,
body: Bytes,
app_state: &NMAppState,
) -> Result<web::HttpResponse, AppError> {
let mut real_body: Option<NMJsonPacket> = None;
let mut json_error = None;
let mut query_error = None;
dbg!(&request.content_type());
dbg!(&request.query_string());
if request.method() == http::Method::POST {
match request.content_type() {
"application/json" => match serde_json::from_slice::<NMJsonPacket>(body.as_ref()) {
Ok(json_body) => real_body = Some(json_body),
Err(error) => json_error = Some(error),
},
"application/x-www-form-urlencoded" => {
match serde_qs::from_bytes::<NMDeviceDataPacket>(body.as_ref()) {
Ok(qs_body) => {
real_body = Some(NMJsonPacket {
devices: Vec::from([qs_body]),
})
}
Err(error) => query_error = Some(error),
}
}
_ => {}
}
} else if request.method() == http::Method::GET {
match serde_qs::from_str::<NMDeviceDataPacket>(request.query_string()) {
Ok(qs_body) => {
real_body = Some(NMJsonPacket {
devices: Vec::from([qs_body]),
})
}
Err(error) => query_error = Some(error),
}
}
if let Some(real_body) = real_body {
for device in real_body.devices {
let mut device_key_str = String::new();
let device_tai_timestamp = device.time
.unwrap_or(Epoch::now().unwrap())
.to_duration_since_j1900()
.to_seconds();
uwrite!(&mut device_key_str, "devices_{}", device.mac)?;
let device_exists: bool = app_state.redis_client.hget(device_key_str.as_str(), "exists").await?;
if !device_exists {
return Err(Error::DeviceNotFound(device.mac))
}
// devices_{device_id}_{tai_timestamp}_{sensor_id}
for sensor in device.values {
let mut device_report_key_str = String::new();
uwrite!(&mut device_report_key_str, "devices_{}_{}_{}", device.mac, device_tai_timestamp, sensor.mac)?;
let mut device_report_key_str = String::new();
app_state.redis_client.hset(device_key_str.as_str(), HashMap::from([
// TODO
])).await?;
}
}
} else {
return Err(AppError::UnknownBody {
json_err: json_error,
query_error,
});
}
Ok(web::HttpResponse::build(StatusCode::OK).finish())
}

View file

@ -1,21 +1,14 @@
use std::collections::HashSet;
use std::num::ParseFloatError;
use std::str::FromStr;
use crate::ingest_protocol::error::Error;
use crate::ingest_protocol::parser::parse_mac_address;
use crate::ingest_protocol::{NMDeviceDataPacket, NMJsonPacket, SensorValue};
use crate::web_server::app_error::AppError;
use ntex::http::{HttpMessage, StatusCode};
use ntex::util::{Bytes, HashMap};
use ntex::{http, web};
use std::sync::Arc;
use fred::bytes_utils::Str;
use hifitime::efmt::consts::ISO8601;
use hifitime::Epoch;
use ntex::util::HashMap;
use rust_decimal::Decimal;
use thiserror::Error;
use crate::ingest_protocol::error::Error;
use crate::ingest_protocol::{NMDeviceDataPacket, SensorValue};
use crate::ingest_protocol::parser::parse_mac_address;
/// В иделае было бы хорошо сделать всё как у [serde_json::Error], но это слишком большая морока
#[derive(Error, Clone, Debug)]
@ -118,56 +111,4 @@ pub async fn parse_nm_qs_format(input: &str) -> Result<NMDeviceDataPacket, QSPar
};
Ok(device_data)
}
pub async fn device_handler<'a>(
request: web::HttpRequest,
body: Bytes,
) -> Result<web::HttpResponse, AppError> {
let mut real_body: Option<NMJsonPacket> = None;
let mut json_error = None;
let mut query_error = None;
dbg!(&request.content_type());
dbg!(&request.query_string());
if request.method() == http::Method::POST {
match request.content_type() {
"application/json" => match serde_json::from_slice::<NMJsonPacket>(body.as_ref()) {
Ok(json_body) => real_body = Some(json_body),
Err(error) => json_error = Some(error),
},
"application/x-www-form-urlencoded" => {
match serde_qs::from_bytes::<NMDeviceDataPacket>(body.as_ref()) {
Ok(qs_body) => {
real_body = Some(NMJsonPacket {
devices: Vec::from([qs_body]),
})
}
Err(error) => query_error = Some(error),
}
}
_ => {}
}
} else if request.method() == http::Method::GET {
match serde_qs::from_str::<NMDeviceDataPacket>(request.query_string()) {
Ok(qs_body) => {
real_body = Some(NMJsonPacket {
devices: Vec::from([qs_body]),
})
}
Err(error) => query_error = Some(error),
}
}
if let Some(_body) = real_body {
// TODO
} else {
return Err(AppError::UnknownBody {
json_err: json_error,
query_error,
});
}
Ok(web::HttpResponse::build(StatusCode::OK).finish())
}
}