Fixed clippy, updated dependencies
Some checks failed
Build Project / test (push) Failing after 9m3s
Some checks failed
Build Project / test (push) Failing after 9m3s
This commit is contained in:
14
Cargo.toml
14
Cargo.toml
@@ -1,23 +1,23 @@
|
||||
[package]
|
||||
name = "iot-cloud"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
actix-service = "2.0.2"
|
||||
actix-web = "4.4.0"
|
||||
chrono = { version = "0.4.31", features = ["serde"] }
|
||||
actix-service = "2.0"
|
||||
actix-web = "4.11"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
dotenvy = "0.15"
|
||||
env_logger = "0.11"
|
||||
log = "0.4.20"
|
||||
log = "0.4"
|
||||
semver = "1.0.25"
|
||||
serde = "1.0.188"
|
||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls", "postgres", "migrate", "chrono", "mac_address"] }
|
||||
sqlx-cli = "0.8"
|
||||
strum = { version = "0.26.3", features = ["derive"] }
|
||||
thiserror = "1.0"
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
thiserror = "2.0"
|
||||
tokio = { version = "1", features = ["fs", "rt-multi-thread"] }
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ impl Database {
|
||||
Database { conn_pool: pool }
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to connect to the database: {:?}", err);
|
||||
error!("Failed to connect to the database: {err:?}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ impl Database {
|
||||
match migrate!().run(&self.conn_pool).await {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
error!("Error when running migrations {}", e);
|
||||
error!("Error when running migrations {e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
@@ -65,12 +65,13 @@ impl Database {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn update_display_name(
|
||||
&self,
|
||||
device_id: &MacAddress,
|
||||
display_name: &str,
|
||||
) -> Result<(), DatabaseError> {
|
||||
info!("Adding Displayname {display_name} to Device with ID {device_id}");
|
||||
info!("Updating Displayname to {display_name} for Device with ID {device_id}");
|
||||
query!(
|
||||
"UPDATE Devices SET display_name = $1 WHERE id = $2;",
|
||||
display_name,
|
||||
@@ -93,7 +94,7 @@ impl Database {
|
||||
let exists = match exists_result {
|
||||
Ok(res) => res.count > Some(0),
|
||||
Err(err) => {
|
||||
error!("Error checking table existence: {:?}", err);
|
||||
error!("Error checking table existence: {err:?}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ async fn receive_telemetry(
|
||||
data: web::Data<AppState>,
|
||||
telemetry_message: web::Json<TelemetryMessageFromDevice>,
|
||||
) -> impl Responder {
|
||||
info!("POST - telementry - Processing device id {}", device_id);
|
||||
info!("POST - telementry - Processing device id {device_id}");
|
||||
let Ok(mac_converted) = parse_mac_address(&device_id) else {
|
||||
return HttpResponse::InternalServerError();
|
||||
};
|
||||
@@ -21,10 +21,10 @@ async fn receive_telemetry(
|
||||
match data.db.create_device_if_not_exists(&mac_converted).await {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
error!("Error creating new device: {}", e);
|
||||
error!("Error creating new device: {e}");
|
||||
return HttpResponse::InternalServerError();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
match data
|
||||
.db
|
||||
@@ -33,7 +33,7 @@ async fn receive_telemetry(
|
||||
{
|
||||
Ok(()) => HttpResponse::Created(),
|
||||
Err(e) => {
|
||||
error!("adding Telemetry message to DB failed \n{}", e);
|
||||
error!("adding Telemetry message to DB failed \n{e}");
|
||||
HttpResponse::InternalServerError()
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ async fn receive_telemetry(
|
||||
|
||||
#[get("/telemetry/{device_id}")]
|
||||
async fn get_telemetry(device_id: web::Path<String>, data: web::Data<AppState>) -> impl Responder {
|
||||
info!("GET - telementry - Processing device id {}", device_id);
|
||||
info!("GET - telementry - Processing device id {device_id}");
|
||||
let Ok(mac_converted) = parse_mac_address(&device_id) else {
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
};
|
||||
@@ -49,7 +49,7 @@ async fn get_telemetry(device_id: web::Path<String>, data: web::Data<AppState>)
|
||||
let messages = match data.db.get_telemetry_for_id(&mac_converted).await {
|
||||
Ok(msgs) => msgs,
|
||||
Err(e) => {
|
||||
error!("Getting Telemetry Messages from DB failed \n{}", e);
|
||||
error!("Getting Telemetry Messages from DB failed \n{e}");
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
}
|
||||
};
|
||||
@@ -62,7 +62,7 @@ async fn receive_value(
|
||||
data: web::Data<AppState>,
|
||||
value_message: web::Json<ValueMessageFromDevice>,
|
||||
) -> impl Responder {
|
||||
info!("POST - value - Processing device id {}", device_id);
|
||||
info!("POST - value - Processing device id {device_id}");
|
||||
let Ok(mac_converted) = parse_mac_address(&device_id) else {
|
||||
return HttpResponse::InternalServerError();
|
||||
};
|
||||
@@ -70,15 +70,15 @@ async fn receive_value(
|
||||
match data.db.create_device_if_not_exists(&mac_converted).await {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
error!("Error creating new device: {}", e);
|
||||
error!("Error creating new device: {e}");
|
||||
return HttpResponse::InternalServerError();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
match data.db.add_value(&value_message, &mac_converted).await {
|
||||
Ok(()) => HttpResponse::Created(),
|
||||
Err(e) => {
|
||||
error!("adding Telemetry message to DB failed \n{}", e);
|
||||
error!("adding Telemetry message to DB failed \n{e}");
|
||||
HttpResponse::InternalServerError()
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ async fn receive_value(
|
||||
|
||||
#[get("/value/{device_id}")]
|
||||
async fn get_value(device_id: web::Path<String>, data: web::Data<AppState>) -> impl Responder {
|
||||
info!("GET - value - Processing device id {}", device_id);
|
||||
info!("GET - value - Processing device id {device_id}");
|
||||
let Ok(mac_converted) = parse_mac_address(&device_id) else {
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
};
|
||||
@@ -94,7 +94,7 @@ async fn get_value(device_id: web::Path<String>, data: web::Data<AppState>) -> i
|
||||
let messages = match data.db.get_values_for_id(&mac_converted).await {
|
||||
Ok(msgs) => msgs,
|
||||
Err(e) => {
|
||||
error!("Getting Values from DB failed \n{}", e);
|
||||
error!("Getting Values from DB failed \n{e}");
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
}
|
||||
};
|
||||
@@ -107,7 +107,7 @@ async fn get_devices(data: web::Data<AppState>) -> impl Responder {
|
||||
let devices = match data.db.get_devices().await {
|
||||
Ok(devs) => devs,
|
||||
Err(e) => {
|
||||
error!("Getting Devices from DB failed \n{}", e);
|
||||
error!("Getting Devices from DB failed \n{e}");
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,18 +38,18 @@ async fn upload_firmware(
|
||||
.with_extension("bin");
|
||||
|
||||
if firmware_path.is_file() {
|
||||
warn!("{service} with product: {device}, config: {config} and version: {version} at path {firmware_path:?} already exists, cant upload");
|
||||
return HttpResponse::Conflict().body(format!("{firmware_path:?}"));
|
||||
warn!("{service} with product: {device}, config: {config} and version: {version} at path {} already exists, cant upload", firmware_path.display());
|
||||
return HttpResponse::Conflict().body(format!("{}", firmware_path.display()));
|
||||
}
|
||||
|
||||
info!("Uploading {service} with product: {device}, config: {config} and version: {version} to {firmware_path:?}");
|
||||
info!("Uploading {service} with product: {device}, config: {config} and version: {version} to {}", firmware_path.display());
|
||||
|
||||
fs::create_dir_all(&firmware_folder).unwrap();
|
||||
let x = tokio::fs::write(&firmware_path, &body).await;
|
||||
debug!("{x:?}");
|
||||
|
||||
debug!("pruning now");
|
||||
prune_files(firmware_folder, service, 3);
|
||||
prune_files(&firmware_folder, &service, 3);
|
||||
|
||||
HttpResponse::Ok().body(format!("Firmware version {version} uploaded successfully"))
|
||||
|
||||
@@ -105,7 +105,7 @@ async fn serve_firmware(
|
||||
let file_path = fw_root_path.join(&file_path);
|
||||
|
||||
|
||||
info!("Requested firmware for product: {product}, config: {config} and version: {version}, expected to be stored at {file_path:?}");
|
||||
info!("Requested firmware for product: {product}, config: {config} and version: {version}, expected to be stored at {}", file_path.display());
|
||||
|
||||
if file_path.exists() {
|
||||
info!("File exists, serving download now");
|
||||
|
||||
@@ -42,7 +42,7 @@ async fn main() -> std::io::Result<()> {
|
||||
firmwares_path: PathBuf::from(firmware_path.clone()),
|
||||
hostname: external_url.clone(),
|
||||
}))
|
||||
.app_data(web::PayloadConfig::new(1 * 1024 * 1024 * 1024)) //1GB
|
||||
.app_data(web::PayloadConfig::new(2 * 1024 * 1024 * 1024)) //1GB
|
||||
.service(device_telemetry_api::receive_telemetry)
|
||||
.service(device_telemetry_api::get_telemetry)
|
||||
.service(device_telemetry_api::receive_value)
|
||||
|
||||
@@ -92,7 +92,7 @@ pub enum BoardType {
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, EnumString, PartialEq, Debug, Display)]
|
||||
#[strum(ascii_case_insensitive, serialize_all = "snake_case")]
|
||||
#[strum(ascii_case_insensitive, serialize_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum BoardConfig {
|
||||
INA226,
|
||||
INA233,
|
||||
@@ -105,6 +105,7 @@ pub struct AppState {
|
||||
pub hostname: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct DeviceMetadata {
|
||||
pub display_name: String,
|
||||
|
||||
20
src/util.rs
20
src/util.rs
@@ -1,4 +1,4 @@
|
||||
use std::{cmp::Reverse, fs, path::PathBuf};
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use log::{error, info};
|
||||
use semver::Version;
|
||||
@@ -47,7 +47,7 @@ pub fn get_files(
|
||||
root_path: &PathBuf,
|
||||
hostname: &str,
|
||||
) -> Result<Vec<OTAConfiguration>, GetFilesError> {
|
||||
info!("Getting all files from path {root_path:?}");
|
||||
info!("Getting all files from path {}", root_path.display());
|
||||
let mut configs = Vec::new();
|
||||
let product_name = root_path
|
||||
.file_name()
|
||||
@@ -59,7 +59,7 @@ pub fn get_files(
|
||||
info!("Reading entry: {entry:?}");
|
||||
let path = entry.path();
|
||||
if path.is_file() {
|
||||
info!("processing file: {:?}", path);
|
||||
info!("processing file: {}", path.display());
|
||||
// Splits the filename at the underscores. This is safe to do as names get sanitized on upload and are only uploaded by the pipeline
|
||||
let split_name: Vec<_> = path
|
||||
.file_name()
|
||||
@@ -81,22 +81,22 @@ pub fn get_files(
|
||||
let fw_url =
|
||||
format!("{hostname}/{service}/{board_type}/{board_config}/{version_replaced}.bin");
|
||||
let cfg = OTAConfiguration {
|
||||
version: version,
|
||||
version,
|
||||
url: fw_url,
|
||||
board: Some(board_type),
|
||||
config: Some(board_config),
|
||||
};
|
||||
configs.push(cfg);
|
||||
} else if path.is_dir() {
|
||||
println!("Directory: {path:?}");
|
||||
println!("Directory: {}", path.display());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(configs)
|
||||
}
|
||||
|
||||
pub fn prune_files(path: PathBuf, service: Services, keep_last: usize) {
|
||||
let Ok(mut config_list) = get_files(&path, "irrelevant") else {
|
||||
pub fn prune_files(path: &PathBuf, service: &Services, keep_last: usize) {
|
||||
let Ok(mut config_list) = get_files(path, "irrelevant") else {
|
||||
error!("failed to get file list for pruning");
|
||||
return
|
||||
};
|
||||
@@ -110,7 +110,7 @@ pub fn prune_files(path: PathBuf, service: Services, keep_last: usize) {
|
||||
if let Err(e) = fs::remove_file(&path_to_remove) {
|
||||
error!("Failed to delete {path_to_remove}, {e:?}");
|
||||
return;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,13 +122,13 @@ mod tests {
|
||||
fn test_file_loading() {
|
||||
let expected_1 = OTAConfiguration {
|
||||
version: Version::parse("1.2.3").unwrap(),
|
||||
url: "example.com/firmware/waterlevel/INA233/1_2_3.bin".to_string(),
|
||||
url: "example.com/firmware/waterlevel/INA233/1-2-3.bin".to_string(),
|
||||
board: Some(BoardType::Waterlevel),
|
||||
config: Some(BoardConfig::INA233),
|
||||
};
|
||||
let expected_2 = OTAConfiguration {
|
||||
version: Version::parse("4.5.6").unwrap(),
|
||||
url: "example.com/firmware/waterlevel/INA226/4_5_6.bin".to_string(),
|
||||
url: "example.com/firmware/waterlevel/INA226/4-5-6.bin".to_string(),
|
||||
board: Some(BoardType::Waterlevel),
|
||||
config: Some(BoardConfig::INA226),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user