From 379de4bdb596a346e01a6c27090ee26d567e07ce Mon Sep 17 00:00:00 2001 From: Benjamin Sherriff Date: Sat, 21 Oct 2023 12:32:50 -0400 Subject: [PATCH] Refactored db directory --- service/Cargo.toml | 3 +- service/migrations/000011_create_users/up.sql | 2 + service/src/auth/mod.rs | 4 +- service/src/auth/model.rs | 14 +++- service/src/auth/routes.rs | 8 +- service/src/bot/api/routes.rs | 2 +- service/src/bot/commands/audio/play.rs | 2 +- service/src/bot/commands/audio/volume.rs | 2 +- service/src/bot/handler.rs | 2 +- service/src/{db => dnd}/backgrounds/mod.rs | 0 service/src/{db => dnd}/bestiary/mod.rs | 0 service/src/{db => dnd}/classes/mod.rs | 0 service/src/{db => dnd}/classes/model.rs | 0 service/src/{db => dnd}/conditions/mod.rs | 0 service/src/{db => dnd}/feats/mod.rs | 0 service/src/{db => dnd}/items/mod.rs | 0 service/src/dnd/mod.rs | 13 ++++ service/src/{db => dnd}/options/mod.rs | 0 service/src/{db => dnd}/races/mod.rs | 0 service/src/{db => dnd}/spells/mod.rs | 0 service/src/{db => dnd}/spells/model.rs | 16 ++-- service/src/{db => dnd}/spells/routes.rs | 2 +- service/src/{db => dnd}/spells/types.rs | 0 service/src/lib.rs | 18 +++++ service/src/main.rs | 15 ++-- service/src/{db => storage}/guilds/mod.rs | 0 service/src/{db => storage}/guilds/model.rs | 2 +- service/src/{db => storage}/messages/mod.rs | 0 service/src/{db => storage}/messages/model.rs | 8 +- .../src/{db => storage}/messages/routes.rs | 2 +- service/src/{db => storage}/mod.rs | 74 ++++++++++--------- service/src/{db => storage}/schema.rs | 2 + 32 files changed, 124 insertions(+), 67 deletions(-) rename service/src/{db => dnd}/backgrounds/mod.rs (100%) rename service/src/{db => dnd}/bestiary/mod.rs (100%) rename service/src/{db => dnd}/classes/mod.rs (100%) rename service/src/{db => dnd}/classes/model.rs (100%) rename service/src/{db => dnd}/conditions/mod.rs (100%) rename service/src/{db => dnd}/feats/mod.rs (100%) rename service/src/{db => dnd}/items/mod.rs (100%) rename service/src/{db => dnd}/options/mod.rs (100%) rename service/src/{db => dnd}/races/mod.rs (100%) rename service/src/{db => dnd}/spells/mod.rs (100%) rename service/src/{db => dnd}/spells/model.rs (96%) rename service/src/{db => dnd}/spells/routes.rs (98%) rename service/src/{db => dnd}/spells/types.rs (100%) rename service/src/{db => storage}/guilds/mod.rs (100%) rename service/src/{db => storage}/guilds/model.rs (95%) rename service/src/{db => storage}/messages/mod.rs (100%) rename service/src/{db => storage}/messages/model.rs (96%) rename service/src/{db => storage}/messages/routes.rs (96%) rename service/src/{db => storage}/mod.rs (53%) rename service/src/{db => storage}/schema.rs (94%) diff --git a/service/Cargo.toml b/service/Cargo.toml index fc7dd6d..36385a4 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -29,6 +29,7 @@ jsonwebtoken = "9.0.0" redis = { version = "0.23.3", features = ["tokio-comp", "connection-manager", "r2d2"] } base64 = "0.21.4" rust-s3 = "0.33.0" +minio = "0.1.0" [dependencies.tokio] version = "1.32.0" @@ -46,7 +47,7 @@ features = ["json", "rustls-tls"] [dependencies.diesel] version = "2.1.2" default-features = false -features = ["postgres", "32-column-tables", "serde_json", "r2d2", "with-deprecated"] +features = ["postgres", "chrono", "32-column-tables", "serde_json", "r2d2", "with-deprecated"] [dependencies.serenity] version = "0.11.6" diff --git a/service/migrations/000011_create_users/up.sql b/service/migrations/000011_create_users/up.sql index 0adabf0..ac207e6 100644 --- a/service/migrations/000011_create_users/up.sql +++ b/service/migrations/000011_create_users/up.sql @@ -4,5 +4,7 @@ CREATE TABLE IF NOT EXISTS users ( role TEXT NOT NULL, first_name TEXT NOT NULL, last_name TEXT NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT NOW(), + updated_at TIMESTAMP NOT NULL DEFAULT NOW(), verified BOOLEAN NOT NULL DEFAULT FALSE ); \ No newline at end of file diff --git a/service/src/auth/mod.rs b/service/src/auth/mod.rs index 8968b48..fc63e4d 100644 --- a/service/src/auth/mod.rs +++ b/service/src/auth/mod.rs @@ -15,7 +15,8 @@ use siren::ServiceError; #[derive(Debug, Serialize, Deserialize)] struct TokenClaims { sub: String, // Subject - token_uuid: String, // Issuer + token_uuid: String, // Token UUID + iss: String, // Issuer exp: i64, // Expiration time iat: i64, // Issued At nbf: i64 // Not Before @@ -73,6 +74,7 @@ pub fn generate_token(email: &str, ttl: i64, private_key: &str) -> Result Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; // Check if the user exists by email, case insensitive let user = users::table @@ -69,12 +73,14 @@ pub struct InsertUser { pub role: String, pub first_name: String, pub last_name: String, + pub updated_at: chrono::NaiveDateTime, + pub created_at: chrono::NaiveDateTime, pub verified: bool, } impl InsertUser { pub fn insert(user: Self) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let user = diesel::insert_into(users::table) .values(user) .get_result(&mut conn)?; @@ -141,7 +147,7 @@ impl FromRequest for JwtAuth { let access_token_uuid = uuid::Uuid::parse_str(&access_token_details.token_uuid.to_string()).unwrap(); - let mut conn = match crate::db::redis_connection() { + let mut conn = match crate::storage::redis_connection() { Ok(conn) => conn, Err(err) => { error!("Failed to get redis connection: {}", err); diff --git a/service/src/auth/routes.rs b/service/src/auth/routes.rs index 24480a8..895461d 100644 --- a/service/src/auth/routes.rs +++ b/service/src/auth/routes.rs @@ -6,7 +6,7 @@ use redis::AsyncCommands; use serde::{Serialize, Deserialize}; use siren::ServiceError; -use crate::{auth::{LoginRequest, RegisterUser, InsertUser, QueryUser, verify_password, JwtAuth, verify_token, generate_access_token, generate_refresh_token}, db}; +use crate::{auth::{LoginRequest, RegisterUser, InsertUser, QueryUser, verify_password, JwtAuth, verify_token, generate_access_token, generate_refresh_token}, storage}; #[post("/register")] async fn register(user: web::Json) -> HttpResponse { @@ -58,7 +58,7 @@ async fn login(request: web::Json) -> HttpResponse { } }; - let mut conn = match db::redis_async_connection().await { + let mut conn = match storage::redis_async_connection().await { Ok(conn) => conn, Err(err) => { error!("Failed to get redis connection: {}", err); @@ -169,7 +169,7 @@ async fn refresh(req: HttpRequest) -> HttpResponse { } }; - let mut conn = match db::redis_async_connection().await { + let mut conn = match storage::redis_async_connection().await { Ok(conn) => conn, Err(err) => { error!("Failed to get redis connection: {}", err); @@ -292,7 +292,7 @@ async fn logout(req: HttpRequest, auth: JwtAuth) -> HttpResponse { Err(err) => return ResponseError::error_response(&err) }; - let mut conn = match db::redis_async_connection().await { + let mut conn = match storage::redis_async_connection().await { Ok(conn) => conn, Err(err) => { error!("Failed to get redis connection: {}", err); diff --git a/service/src/bot/api/routes.rs b/service/src/bot/api/routes.rs index d1e2576..25c8be5 100644 --- a/service/src/bot/api/routes.rs +++ b/service/src/bot/api/routes.rs @@ -6,7 +6,7 @@ use serde::{Serialize, Deserialize}; use serenity::model::prelude::{GuildChannel, ChannelType}; use siren::ServiceError; -use crate::{AppState, bot::commands::audio::{play::play_track, join}, db::guilds::QueryGuild, auth::{JwtAuth, verify_role}}; +use crate::{AppState, bot::commands::audio::{play::play_track, join}, storage::guilds::QueryGuild, auth::{JwtAuth, verify_role}}; #[get("/guilds")] async fn get_guilds(data: web::Data>, auth: JwtAuth) -> HttpResponse { diff --git a/service/src/bot/commands/audio/play.rs b/service/src/bot/commands/audio/play.rs index 3fb0c7c..b4ffbae 100644 --- a/service/src/bot/commands/audio/play.rs +++ b/service/src/bot/commands/audio/play.rs @@ -10,7 +10,7 @@ use siren::ServiceError; use songbird::{EventHandler, Songbird}; use crate::bot::commands::audio::{leave, add_song, get_songbird}; -use crate::db::guilds::QueryGuild; +use crate::storage::guilds::QueryGuild; use super::{create_response, edit_response, join_by_user}; diff --git a/service/src/bot/commands/audio/volume.rs b/service/src/bot/commands/audio/volume.rs index 9a3ece3..7bf96ec 100644 --- a/service/src/bot/commands/audio/volume.rs +++ b/service/src/bot/commands/audio/volume.rs @@ -7,7 +7,7 @@ use serenity::builder::CreateApplicationCommand; use serenity::model::application::interaction::application_command::ApplicationCommandInteraction; use songbird::Songbird; -use crate::db::guilds::InsertGuild; +use crate::storage::guilds::InsertGuild; use super::{get_songbird, create_response, edit_response}; diff --git a/service/src/bot/handler.rs b/service/src/bot/handler.rs index f45d3d1..b7c3db5 100644 --- a/service/src/bot/handler.rs +++ b/service/src/bot/handler.rs @@ -5,7 +5,7 @@ use serenity::model::gateway::Ready; use serenity::model::channel::Message; use serenity::prelude::*; -use crate::db::guilds::InsertGuild; +use crate::storage::guilds::InsertGuild; use super::commands; use super::commands::audio::create_response; diff --git a/service/src/db/backgrounds/mod.rs b/service/src/dnd/backgrounds/mod.rs similarity index 100% rename from service/src/db/backgrounds/mod.rs rename to service/src/dnd/backgrounds/mod.rs diff --git a/service/src/db/bestiary/mod.rs b/service/src/dnd/bestiary/mod.rs similarity index 100% rename from service/src/db/bestiary/mod.rs rename to service/src/dnd/bestiary/mod.rs diff --git a/service/src/db/classes/mod.rs b/service/src/dnd/classes/mod.rs similarity index 100% rename from service/src/db/classes/mod.rs rename to service/src/dnd/classes/mod.rs diff --git a/service/src/db/classes/model.rs b/service/src/dnd/classes/model.rs similarity index 100% rename from service/src/db/classes/model.rs rename to service/src/dnd/classes/model.rs diff --git a/service/src/db/conditions/mod.rs b/service/src/dnd/conditions/mod.rs similarity index 100% rename from service/src/db/conditions/mod.rs rename to service/src/dnd/conditions/mod.rs diff --git a/service/src/db/feats/mod.rs b/service/src/dnd/feats/mod.rs similarity index 100% rename from service/src/db/feats/mod.rs rename to service/src/dnd/feats/mod.rs diff --git a/service/src/db/items/mod.rs b/service/src/dnd/items/mod.rs similarity index 100% rename from service/src/db/items/mod.rs rename to service/src/dnd/items/mod.rs diff --git a/service/src/dnd/mod.rs b/service/src/dnd/mod.rs index e69de29..d8a2b34 100644 --- a/service/src/dnd/mod.rs +++ b/service/src/dnd/mod.rs @@ -0,0 +1,13 @@ +pub mod backgrounds; +pub mod bestiary; +pub mod classes; +pub mod conditions; +pub mod feats; +pub mod items; +pub mod options; +pub mod races; +pub mod spells; + +pub fn load_data(data_dir_path: &str) { + spells::load_data(data_dir_path); +} \ No newline at end of file diff --git a/service/src/db/options/mod.rs b/service/src/dnd/options/mod.rs similarity index 100% rename from service/src/db/options/mod.rs rename to service/src/dnd/options/mod.rs diff --git a/service/src/db/races/mod.rs b/service/src/dnd/races/mod.rs similarity index 100% rename from service/src/db/races/mod.rs rename to service/src/dnd/races/mod.rs diff --git a/service/src/db/spells/mod.rs b/service/src/dnd/spells/mod.rs similarity index 100% rename from service/src/db/spells/mod.rs rename to service/src/dnd/spells/mod.rs diff --git a/service/src/db/spells/model.rs b/service/src/dnd/spells/model.rs similarity index 96% rename from service/src/db/spells/model.rs rename to service/src/dnd/spells/model.rs index a2d460b..9604178 100644 --- a/service/src/db/spells/model.rs +++ b/service/src/dnd/spells/model.rs @@ -2,7 +2,9 @@ use diesel::prelude::*; use serde::{Deserialize, Serialize}; use siren::ServiceError; -use crate::db::{schema::spells::{self}, classes::AbilityType, conditions::ConditionType}; +use crate::storage::connection; +use crate::storage::schema::spells::{self}; +use crate::dnd::{classes::AbilityType, conditions::ConditionType}; use super::{SchoolType, CastingTime, SpellAttackType, SpellDamageType, Range, Area, Components, Duration, Source, Description, DurationType, Effect}; @@ -61,7 +63,7 @@ impl Default for QueryFilters { impl QuerySpell { pub fn get_all(filters: &QueryFilters, limit: i32, page: i32) -> Result, ServiceError> { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let mut query = spells::table.limit(limit as i64).into_boxed(); // Limit query to page and limit let offset = (page - 1) * limit; @@ -108,7 +110,7 @@ impl QuerySpell { } pub fn get_count(filters: &QueryFilters) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let mut query = spells::table.count().into_boxed(); if let Some(name) = &filters.by_name { query = query.filter(spells::name.ilike(format!("%{}%", name))); @@ -149,7 +151,7 @@ impl QuerySpell { } pub fn get_by_id(id: i32) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let spell = spells::table .filter(spells::id.eq(id)) .first::(&mut conn)?; @@ -157,7 +159,7 @@ impl QuerySpell { } pub fn delete(id: i32) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let spell = diesel::delete(spells::table.filter(spells::id.eq(id))).get_result(&mut conn)?; Ok(spell) } @@ -182,13 +184,13 @@ pub struct InsertSpell { impl InsertSpell { pub fn insert(spell: Self) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let spell = diesel::insert_into(spells::table).values(spell).get_result(&mut conn)?; Ok(spell) } pub fn update(id: i32, spell: Self) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let spell = diesel::update(spells::table.filter(spells::id.eq(id))).set(spell).get_result(&mut conn)?; Ok(spell) } diff --git a/service/src/db/spells/routes.rs b/service/src/dnd/spells/routes.rs similarity index 98% rename from service/src/db/spells/routes.rs rename to service/src/dnd/spells/routes.rs index 4b95e90..62f8eec 100644 --- a/service/src/db/spells/routes.rs +++ b/service/src/dnd/spells/routes.rs @@ -3,7 +3,7 @@ use log::error; use serde::{Serialize, Deserialize}; use siren::{GetResponse, Metadata, ServiceError}; -use crate::{db::spells::{QuerySpell, QueryFilters}, auth::{JwtAuth, verify_role}}; +use crate::{dnd::spells::{QuerySpell, QueryFilters}, auth::{JwtAuth, verify_role}}; use super::{Spell, InsertSpell}; diff --git a/service/src/db/spells/types.rs b/service/src/dnd/spells/types.rs similarity index 100% rename from service/src/db/spells/types.rs rename to service/src/dnd/spells/types.rs diff --git a/service/src/lib.rs b/service/src/lib.rs index 67645ec..9f87271 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -112,6 +112,24 @@ impl From for ServiceError { } } +impl From for ServiceError { + fn from(error: s3::error::S3Error) -> ServiceError { + ServiceError::new(500, format!("Unknown s3 error: {}", error)) + } +} + +impl From for ServiceError { + fn from(error: s3::creds::error::CredentialsError) -> ServiceError { + ServiceError::new(500, format!("Unknown credentials error: {}", error)) + } +} + +impl From for ServiceError { + fn from(error: minio::s3::error::Error) -> ServiceError { + ServiceError::new(500, format!("Unknown minio error: {}", error)) + } +} + impl ResponseError for ServiceError { fn error_response(&self) -> HttpResponse { let status_code = match StatusCode::from_u16(self.status) { diff --git a/service/src/main.rs b/service/src/main.rs index 4322e3f..d114881 100644 --- a/service/src/main.rs +++ b/service/src/main.rs @@ -21,15 +21,15 @@ use dotenv::dotenv; mod auth; mod dnd; mod bot; -mod db; +mod storage; #[actix_web::main] async fn main() -> std::io::Result<()> { dotenv().ok(); env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", "warn,siren=info")); - db::init(); + storage::init(); match env::var("DATA_DIR_PATH") { - Ok(data_dir_path) => db::load_data(&data_dir_path), + Ok(data_dir_path) => dnd::load_data(&data_dir_path), Err(err) => warn!("Unable to load initial database data: {}", err) }; @@ -111,6 +111,11 @@ async fn main() -> std::io::Result<()> { let host = env::var("SERVICE_HOST").unwrap_or("localhost".to_string()); let port = env::var("SERVICE_PORT").unwrap_or("5000".to_string()); + match crate::storage::create_bucket("siren").await { + Ok(_) => {}, + Err(err) => {} + }; + let server = match HttpServer::new(move || { let cors = Cors::default() .allow_any_origin() @@ -121,8 +126,8 @@ async fn main() -> std::io::Result<()> { App::new() .wrap(cors) .app_data(web::Data::new(Arc::clone(&app_data))) - .configure(crate::db::messages::init_routes) - .configure(crate::db::spells::init_routes) + .configure(crate::storage::messages::init_routes) + .configure(crate::dnd::spells::init_routes) .configure(crate::auth::init_routes) .configure(crate::bot::api::init_routes) }) diff --git a/service/src/db/guilds/mod.rs b/service/src/storage/guilds/mod.rs similarity index 100% rename from service/src/db/guilds/mod.rs rename to service/src/storage/guilds/mod.rs diff --git a/service/src/db/guilds/model.rs b/service/src/storage/guilds/model.rs similarity index 95% rename from service/src/db/guilds/model.rs rename to service/src/storage/guilds/model.rs index ababc25..ea89714 100644 --- a/service/src/db/guilds/model.rs +++ b/service/src/storage/guilds/model.rs @@ -2,7 +2,7 @@ use diesel::prelude::*; use serde::{Serialize, Deserialize}; use siren::ServiceError; -use crate::db::{schema::guilds, connection}; +use crate::storage::{schema::guilds, connection}; #[derive(Queryable, QueryableByName, Serialize, Deserialize)] #[diesel(table_name = guilds)] diff --git a/service/src/db/messages/mod.rs b/service/src/storage/messages/mod.rs similarity index 100% rename from service/src/db/messages/mod.rs rename to service/src/storage/messages/mod.rs diff --git a/service/src/db/messages/model.rs b/service/src/storage/messages/model.rs similarity index 96% rename from service/src/db/messages/model.rs rename to service/src/storage/messages/model.rs index a5f9ebb..58351ed 100644 --- a/service/src/db/messages/model.rs +++ b/service/src/storage/messages/model.rs @@ -2,7 +2,7 @@ use diesel::prelude::*; use serde::{Deserialize, Serialize}; use siren::ServiceError; -use crate::db::schema::messages::{self}; +use crate::storage::{schema::messages::{self}, connection}; #[derive(Queryable, Selectable, Serialize, Deserialize)] #[diesel(table_name = messages)] @@ -49,7 +49,7 @@ impl Default for QueryFilters { impl QueryMessage { pub fn get_all(filters: &QueryFilters, limit: i32, page: i32) -> Result, ServiceError> { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let mut query = messages::table.limit(limit as i64).order(messages::created.asc()).into_boxed(); // Limit query to page and limit let offset = (page - 1) * limit; @@ -88,7 +88,7 @@ impl QueryMessage { } pub fn get_count(fitlers: &QueryFilters) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let mut query = messages::table.into_boxed(); // Apply filters if let Some(id) = &fitlers.by_id { @@ -141,7 +141,7 @@ pub struct InsertMessage { impl InsertMessage { pub fn insert(message: Self) -> Result { - let mut conn = crate::db::connection()?; + let mut conn = connection()?; let message = diesel::insert_into(messages::table) .values(message) .get_result(&mut conn)?; diff --git a/service/src/db/messages/routes.rs b/service/src/storage/messages/routes.rs similarity index 96% rename from service/src/db/messages/routes.rs rename to service/src/storage/messages/routes.rs index 507a361..82f284c 100644 --- a/service/src/db/messages/routes.rs +++ b/service/src/storage/messages/routes.rs @@ -3,7 +3,7 @@ use log::error; use serde::{Serialize, Deserialize}; use siren::{GetResponse, Metadata, ServiceError}; -use crate::{db::messages::{QueryMessage, QueryFilters, InsertMessage}, auth::{JwtAuth, verify_role}}; +use crate::{storage::messages::{QueryMessage, QueryFilters, InsertMessage}, auth::{JwtAuth, verify_role}}; #[derive(Serialize, Deserialize)] struct GetAllParams { diff --git a/service/src/db/mod.rs b/service/src/storage/mod.rs similarity index 53% rename from service/src/db/mod.rs rename to service/src/storage/mod.rs index 96b1ac4..6205dc2 100644 --- a/service/src/db/mod.rs +++ b/service/src/storage/mod.rs @@ -1,6 +1,6 @@ use diesel::{r2d2::ConnectionManager as DieselConnectionManager, PgConnection}; -// use redis::{aio::{Connection as RedisConnection, ConnectionManager as RedisConnectionManager}, AsyncCommands}; -use redis::aio::Connection as RedisConnection; +use minio::s3::{client::Client as MinioClient, http::BaseUrl, creds::StaticProvider, args::{MakeBucketArgs, BucketExistsArgs}}; +use redis::{Client as RedisClient, aio::Connection as RedisConnection}; use siren::ServiceError; use crate::diesel_migrations::MigrationHarness; use lazy_static::lazy_static; @@ -8,22 +8,12 @@ use log::{error, info}; use r2d2; use std::env; -pub mod backgrounds; -pub mod bestiary; -pub mod classes; -pub mod conditions; -pub mod feats; pub mod guilds; -pub mod items; pub mod messages; -pub mod options; -pub mod races; -pub mod spells; pub mod schema; type DbPool = r2d2::Pool>; pub type DbConnection = r2d2::PooledConnection>; -// type RedisPool = r2d2::Pool; pub const MIGRATIONS: diesel_migrations::EmbeddedMigrations = embed_migrations!(); @@ -38,18 +28,39 @@ lazy_static! { let manager = DieselConnectionManager::::new(url); DbPool::builder().test_on_check_out(true).build(manager).expect("Failed to create db pool") }; - // static ref REDIS_POOL: RedisPool = { - // let host = env::var("REDIS_HOST").unwrap_or("localhost".to_string()); - // let port = env::var("REDIS_PORT").unwrap_or("6379".to_string()); - // let url = format!("redis://{}:{}", host, port); - // let client = redis::Client::open(url).expect("Failed to create redis client"); - // let manager = RedisConnectionManager::new(client); - // "".to_string() - // }; + static ref REDIS: RedisClient = { + let host = env::var("REDIS_HOST").unwrap_or("localhost".to_string()); + let port = env::var("REDIS_PORT").unwrap_or("6379".to_string()); + let url = format!("redis://{}:{}", host, port); + RedisClient::open(url).expect("Failed to create redis client") + }; + static ref MINIO: MinioClient = { + let url = env::var("MINIO_URL").unwrap_or("localhost".to_string()); + let port = env::var("MINIO_PORT").unwrap_or("9000".to_string()); + let base_url = format!("http://{}:{}", url, port).parse::().unwrap(); + + let user = env::var("MINIO_ROOT_USER").expect("MINIO_ROOT_USER is not set"); + let password = env::var("MINIO_ROOT_PASSWORD").expect("MINIO_ROOT_PASSWORD is not set"); + + let static_provider = StaticProvider::new( + &user, + &password, + None + ); + + MinioClient::new( + base_url, + Some(Box::new(static_provider)), + None, + None + ).expect("Failed to create minio client") + }; } pub fn init() { lazy_static::initialize(&POOL); + lazy_static::initialize(&REDIS); + lazy_static::initialize(&MINIO); let mut pool: DbConnection = connection().expect("Failed to get db connection"); match pool.run_pending_migrations(MIGRATIONS) { Ok(_) => info!("Database initialized"), @@ -62,26 +73,21 @@ pub fn connection() -> Result { .map_err(|e| ServiceError::new(500, format!("Failed getting db connection: {}", e))) } -pub fn redis_client() -> Result { - let host = env::var("REDIS_HOST").unwrap_or("localhost".to_string()); - let port = env::var("REDIS_PORT").unwrap_or("6379".to_string()); - let url = format!("redis://{}:{}", host, port); - let client = redis::Client::open(url)?; - Ok(client) -} - pub fn redis_connection() -> Result { - let client = redis_client()?; - let conn = client.get_connection()?; + let conn = REDIS.get_connection()?; Ok(conn) } pub async fn redis_async_connection() -> Result { - let client = redis_client()?; - let conn = client.get_async_connection().await?; + let conn = REDIS.get_async_connection().await?; Ok(conn) } -pub fn load_data(data_dir_path: &str) { - spells::load_data(data_dir_path); +pub async fn create_bucket(bucket_name: &str) -> Result<(), ServiceError> { + let exists = MINIO.bucket_exists(&BucketExistsArgs::new(&bucket_name).unwrap()).await?; + if !exists { + MINIO.make_bucket(&MakeBucketArgs::new(&bucket_name).unwrap()).await?; + } + + Ok(()) } diff --git a/service/src/db/schema.rs b/service/src/storage/schema.rs similarity index 94% rename from service/src/db/schema.rs rename to service/src/storage/schema.rs index 3e6f3e5..6523bf4 100644 --- a/service/src/db/schema.rs +++ b/service/src/storage/schema.rs @@ -46,6 +46,8 @@ diesel::table! { role -> Text, first_name -> Text, last_name -> Text, + updated_at -> Timestamp, + created_at -> Timestamp, verified -> Bool, } } \ No newline at end of file