start rust exporter

This commit is contained in:
Sam 2023-04-09 23:27:40 +02:00
parent 041913675b
commit 2a4195ac03
No known key found for this signature in database
GPG Key ID: B4EF20DDE721CAA1
6 changed files with 1728 additions and 0 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ build
package
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
target

1595
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

4
Cargo.toml Normal file
View File

@ -0,0 +1,4 @@
[workspace]
members = [
"exporter",
]

14
exporter/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "exporter"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.6.12"
dotenvy = "0.15.7"
serde = { version = "1.0.159", features = ["derive"] }
serde_json = "1.0.95"
sqlx = { version = "0.6.3", features= ["runtime-tokio-rustls", "postgres", "json"]}
tokio = { version = "1.27.0", features = ["full"] }
tracing = "0.1.37"
tracing-subscriber = "0.3.16"

90
exporter/src/main.rs Normal file
View File

@ -0,0 +1,90 @@
use std::env;
use std::net::SocketAddr;
use std::sync::Arc;
use axum::{
extract::{Path, State},
http::StatusCode,
routing::get,
Json, Router,
};
use sqlx::{postgres::PgPoolOptions, Pool, Postgres};
use tracing::{error, info};
use tracing_subscriber;
use user::ExportUser;
use crate::user::DBUser;
pub mod user;
struct AppState {
pool: Pool<Postgres>,
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
info!("Loading .env");
dotenvy::dotenv().unwrap();
info!("Connecting to database");
let db_dsn = env::var("DATABASE_URL").expect("DATABASE_URL is not set or invalid!");
let pool = PgPoolOptions::new()
.max_connections(10)
.connect(db_dsn.as_str())
.await
.expect("Could not connect do database!");
info!("Initializing exporter server");
let shared_state = Arc::new(AppState { pool });
let app = Router::new()
.route("/start/:id", get(handler))
.with_state(shared_state);
let port = match env::var("EXPORTER_PORT") {
Ok(val) => val
.parse::<u16>()
.expect("EXPORTER_PORT is not a valid integer!"),
Err(_) => {
error!("EXPORTER_PORT is not set, falling back to port 8081");
8081
}
};
info!(port, "Starting server");
let addr = SocketAddr::from(([127, 0, 0, 1], port));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn handler(
State(state): State<Arc<AppState>>,
Path(user_id): Path<String>,
) -> Result<(StatusCode, Json<ExportUser>), (StatusCode, String)> {
info!(user_id = user_id, "Received thing :)");
let user = match sqlx::query_as!(
DBUser,
"SELECT id, username, display_name FROM users WHERE id = $1",
user_id
)
.fetch_one(&state.pool)
.await
{
Ok(val) => val,
Err(why) => return Err((StatusCode::INTERNAL_SERVER_ERROR, format!("{}", why))),
};
info!(id = user.id, username = user.username, "Got user!");
Ok((StatusCode::ACCEPTED, Json(user.to_export())))
}

24
exporter/src/user.rs Normal file
View File

@ -0,0 +1,24 @@
use serde::Serialize;
pub struct DBUser {
pub id: String,
pub username: String,
pub display_name: Option<String>,
}
impl DBUser {
pub fn to_export(self) -> ExportUser {
ExportUser {
id: self.id,
username: self.username,
display_name: self.display_name,
}
}
}
#[derive(Serialize, Debug)]
pub struct ExportUser {
pub id: String,
pub username: String,
pub display_name: Option<String>,
}