From 3b2f636e418b64cdd4436641262321027f3b6bbf Mon Sep 17 00:00:00 2001 From: Tobias Maier Date: Thu, 14 Sep 2023 20:01:34 +0000 Subject: [PATCH] basic stuff --- .devcontainer/Dockerfile | 2 +- .env | 1 + .vscode/launch.json | 45 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +++- dev.md | 24 +++++++++++++++++++ src/database.rs | 50 ++++++++++++++++++++++++++++++++++++++++ src/main.rs | 39 +++++++++++++++++++++---------- 7 files changed, 151 insertions(+), 14 deletions(-) create mode 100644 .env create mode 100644 .vscode/launch.json create mode 100644 dev.md create mode 100644 src/database.rs diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index e1247cf..d7bc2a4 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ FROM rust:1-bookworm -RUN apt update && apt upgrade -y && apt install fish -y +RUN apt update && apt upgrade -y && apt install fish iputils-ping -y RUN rustup component add clippy rustfmt RUN useradd -ms /bin/fish vscode \ No newline at end of file diff --git a/.env b/.env new file mode 100644 index 0000000..d4d7081 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +DATABASE_URL=postgres://dev:dev@db/iot \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..939bfde --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'iot-cloud'", + "cargo": { + "args": [ + "build", + "--bin=iot-cloud", + "--package=iot-cloud" + ], + "filter": { + "name": "iot-cloud", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'iot-cloud'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=iot-cloud", + "--package=iot-cloud" + ], + "filter": { + "name": "iot-cloud", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index ee8c2e0..372d914 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,6 @@ edition = "2021" [dependencies] actix-web = "4.4.0" -sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls", "postgres" ] } \ No newline at end of file +env_logger = "0.10.0" +log = "0.4.20" +sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls", "postgres" ] } diff --git a/dev.md b/dev.md new file mode 100644 index 0000000..1c9045e --- /dev/null +++ b/dev.md @@ -0,0 +1,24 @@ +# Tables +## Devices +- ID +- display_name + + +## Sensor Data +- timestamp +- value +- device_id +- errorcode + +## Telemetry +- timestamp +- Software Version +- Voltage +- Temperature +- uptime + + +# Endpoints +- /telemetry +- /values +- /ota \ No newline at end of file diff --git a/src/database.rs b/src/database.rs new file mode 100644 index 0000000..4092cc0 --- /dev/null +++ b/src/database.rs @@ -0,0 +1,50 @@ +use log::{info, error}; +use sqlx::{pool, postgres::PgPoolOptions, PgPool, Pool, Postgres, query}; + +#[derive(Clone)] +pub struct Database { + conn_pool: Pool, +} + +impl Database { + pub async fn init(host: &str, user: &str, pass: &str, db_name: &str) -> Database { + match PgPoolOptions::new() + .max_connections(10) + .connect(&format!("postgres://{user}:{pass}@{host}/{db_name}")) + .await + { + Ok(pool) => { + info!("Connection to the database is successful!"); + Database { conn_pool: pool } + } + Err(err) => { + error!("Failed to connect to the database: {:?}", err); + std::process::exit(1); + } + } + } + + pub fn add_telementry(&self){ + info!("Adding telementry") + } + + // Check if the necessary tables exist. If not, create them. TODO auto-migration + pub async fn init_db(&self){ + info!("Checking if required tables exist"); + + let exists = query!( + "SELECT count(*) FROM information_schema.tables WHERE table_name = 'dev';" + ).fetch_one(&self.conn_pool).await; + + let exist = match exists { + Ok(res) => res.count > Some(0), + Err(err) => { + error!("Error checking table existence: {:?}", err); + std::process::exit(1); + } + + }; + + info!("Table exists: {:?}", exist); + } +} diff --git a/src/main.rs b/src/main.rs index d650da8..068b70b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,34 @@ -use actix_web::{get, web, App, HttpServer, Responder}; +use actix_web::{post, web, App, HttpServer, Responder}; +use database::Database; +use log::info; -#[get("/")] -async fn index() -> impl Responder { - "Hello, World!" +mod database; + +struct AppState { + db: Database, } -#[get("/{name}")] -async fn hello(name: web::Path) -> impl Responder { - format!("Hello {}!", &name) +#[post("/telemetry/{device_id}")] +async fn receive_telemetry(device_id: web::Path, data: web::Data) -> impl Responder { + data.db.add_telementry(); + format!("Hello {}!", &device_id) } #[actix_web::main] async fn main() -> std::io::Result<()> { - HttpServer::new(|| App::new().service(index).service(hello)) - .bind(("127.0.0.1", 8080))? - .run() - .await -} \ No newline at end of file + env_logger::init(); + info!("Starting"); + + info!("Connecting to Database"); + let db = Database::init("db", "dev", "dev", "iot").await; + db.init_db().await; + + HttpServer::new(move || { + App::new() + .app_data(web::Data::new(AppState { db: db.clone() })) + .service(receive_telemetry) + }) + .bind(("127.0.0.1", 8080))? + .run() + .await +}