mirror of
https://github.com/bitwarden/server.git
synced 2025-12-10 17:45:21 -06:00
Start scaffolding hosting applications
This commit is contained in:
parent
ab1eaddb18
commit
f2136bb809
29
akd/Cargo.lock
generated
29
akd/Cargo.lock
generated
@ -26,6 +26,19 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aio"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"akd_storage",
|
||||
"common",
|
||||
"publisher",
|
||||
"reader",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "akd"
|
||||
version = "0.11.0"
|
||||
@ -1476,8 +1489,11 @@ dependencies = [
|
||||
name = "publisher"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"akd",
|
||||
"akd_storage",
|
||||
"async-std",
|
||||
"bitwarden-akd-configuration",
|
||||
"common",
|
||||
"tiberius",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@ -1530,6 +1546,19 @@ dependencies = [
|
||||
"getrandom 0.2.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reader"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"akd",
|
||||
"akd_storage",
|
||||
"bitwarden-akd-configuration",
|
||||
"common",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.17"
|
||||
|
||||
@ -16,6 +16,9 @@ unwrap_used = "deny"
|
||||
[workspace.dependencies]
|
||||
akd = "0.11.0"
|
||||
async-trait = "0.1.89"
|
||||
akd_storage = { path = "crates/akd_storage" }
|
||||
bitwarden-akd-configuration = { path = "crates/bitwarden-akd-configuration" }
|
||||
common = { path = "crates/common" }
|
||||
config = "0.15.18"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
tokio = { version = "1.47.1", features = ["full"] }
|
||||
|
||||
19
akd/crates/aio/Cargo.toml
Normal file
19
akd/crates/aio/Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "aio"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license-file.workspace = true
|
||||
keywords.workspace = true
|
||||
|
||||
[dependencies]
|
||||
akd_storage = { workspace = true }
|
||||
common = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
publisher = { path = "../publisher" }
|
||||
reader = { path = "../reader" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
41
akd/crates/aio/src/main.rs
Normal file
41
akd/crates/aio/src/main.rs
Normal file
@ -0,0 +1,41 @@
|
||||
//! AIO process for an AKD. Spins up multiple async tasks to handle publisher and reader roles.
|
||||
//! Requires both read and write permissions to the underlying data stores.
|
||||
//! There should only be one instance of this running at a time for a given AKD.
|
||||
|
||||
use akd_storage::db_config::DbConfig;
|
||||
use common::VrfStorageType;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.init();
|
||||
|
||||
let connection_string = std::env::var("AKD_MSSQL_CONNECTION_STRING")
|
||||
.expect("AKD_MSSQL_CONNECTION_STRING must be set.");
|
||||
let db_config = DbConfig::MsSql {
|
||||
connection_string,
|
||||
pool_size: 10,
|
||||
};
|
||||
|
||||
let db = db_config
|
||||
.connect()
|
||||
.await
|
||||
.expect("Failed to connect to database");
|
||||
let vrf = VrfStorageType::HardCodedAkdVRF;
|
||||
|
||||
// Start the publisher write job
|
||||
let _write_job_handle = {
|
||||
let db = db.clone();
|
||||
let vrf = vrf.clone();
|
||||
tokio::spawn(async move {
|
||||
publisher::start_write_job(db, vrf).await;
|
||||
})
|
||||
};
|
||||
|
||||
// Create a router with both publisher and reader routes
|
||||
todo!();
|
||||
|
||||
// Start the web server
|
||||
todo!();
|
||||
}
|
||||
@ -21,6 +21,8 @@ mod temp_table;
|
||||
pub mod akd_storage_config;
|
||||
pub mod db_config;
|
||||
|
||||
/// Enum to represent different database types supported by the storage layer.
|
||||
/// Each variant is cheap to clone for reuse across threads.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DatabaseType {
|
||||
MsSql(MsSql),
|
||||
|
||||
@ -12,7 +12,7 @@ path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
akd = { workspace = true }
|
||||
akd_storage = { path = "../akd_storage" }
|
||||
akd_storage = { workspace = true}
|
||||
anyhow = "1"
|
||||
async-trait = { workspace = true }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
|
||||
@ -9,7 +9,7 @@ keywords.workspace = true
|
||||
[dependencies]
|
||||
akd = "0.11.0"
|
||||
async-trait = { workspace = true }
|
||||
akd_storage = { path = "../akd_storage" }
|
||||
akd_storage = { workspace = true}
|
||||
config = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
thiserror = "2.0.17"
|
||||
|
||||
@ -7,7 +7,10 @@ license-file.workspace = true
|
||||
keywords.workspace = true
|
||||
|
||||
[dependencies]
|
||||
akd_storage = { path = "../akd_storage" }
|
||||
akd = { workspace = true }
|
||||
akd_storage = { workspace = true}
|
||||
bitwarden-akd-configuration = { workspace = true}
|
||||
common = { workspace = true }
|
||||
tokio-util = {version = "0.7.16", features = ["compat"] }
|
||||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
||||
22
akd/crates/publisher/src/lib.rs
Normal file
22
akd/crates/publisher/src/lib.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use akd::{directory::Directory, storage::StorageManager};
|
||||
use akd_storage::DatabaseType;
|
||||
use bitwarden_akd_configuration::BitwardenV1Configuration;
|
||||
use common::VrfStorageType;
|
||||
use tracing::instrument;
|
||||
|
||||
struct AppState {
|
||||
directory: Directory<BitwardenV1Configuration, DatabaseType, VrfStorageType>,
|
||||
}
|
||||
|
||||
#[instrument(skip_all, name = "publisher_start")]
|
||||
pub async fn start_write_job(_db: DatabaseType, vrf: VrfStorageType) {
|
||||
let storage_manager = StorageManager::new_no_cache(_db);
|
||||
let _app_state = AppState {
|
||||
directory: Directory::new(storage_manager, vrf).await.unwrap(),
|
||||
};
|
||||
println!("Publisher started");
|
||||
}
|
||||
|
||||
pub async fn start_web_server(_db: DatabaseType) {
|
||||
println!("Web server started");
|
||||
}
|
||||
@ -1,17 +1,48 @@
|
||||
//! The Publisher crate is responsible for tracking insert requests into the AKD and performing them as batches on a schedule.
|
||||
//! Write permissions are needed to the underlying data stores.
|
||||
//! There should only be one instance of this running at a time for a given AKD.
|
||||
|
||||
use akd_storage::db_config::DbConfig;
|
||||
use publisher::{start_web_server, start_write_job};
|
||||
use tracing::info;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.init();
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.init();
|
||||
|
||||
// Read connection string from env var
|
||||
let connection_string = std::env::var("AKD_MSSQL_CONNECTION_STRING").expect("AKD_MSSQL_CONNECTION_STRING must be set.");
|
||||
let connection_string = std::env::var("AKD_MSSQL_CONNECTION_STRING")
|
||||
.expect("AKD_MSSQL_CONNECTION_STRING must be set.");
|
||||
let db_config = DbConfig::MsSql {
|
||||
connection_string,
|
||||
pool_size: 10,
|
||||
};
|
||||
|
||||
let mssql = akd_storage::ms_sql::MsSql::builder(connection_string)
|
||||
.pool_size(10)
|
||||
.build()
|
||||
let db = db_config
|
||||
.connect()
|
||||
.await
|
||||
.expect("Failed to create MsSql instance");
|
||||
.expect("Failed to connect to database");
|
||||
let vrf = common::VrfStorageType::HardCodedAkdVRF;
|
||||
|
||||
mssql.migrate().await.expect("Failed to run migrations");
|
||||
let write_job_handle = {
|
||||
let db = db.clone();
|
||||
tokio::spawn(async move {
|
||||
start_write_job(db, vrf).await;
|
||||
})
|
||||
};
|
||||
let web_server_handle = tokio::spawn(async move {
|
||||
start_web_server(db).await;
|
||||
});
|
||||
|
||||
// Wait for both services to complete
|
||||
tokio::select! {
|
||||
_ = write_job_handle => {
|
||||
info!("Write job completed");
|
||||
}
|
||||
_ = web_server_handle => {
|
||||
info!("Web service completed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
akd/crates/reader/Cargo.toml
Normal file
19
akd/crates/reader/Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "reader"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license-file.workspace = true
|
||||
keywords.workspace = true
|
||||
|
||||
[dependencies]
|
||||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
akd = { workspace = true }
|
||||
akd_storage = { workspace = true}
|
||||
bitwarden-akd-configuration = { workspace = true}
|
||||
common = { workspace = true}
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
21
akd/crates/reader/src/lib.rs
Normal file
21
akd/crates/reader/src/lib.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use akd::{directory::ReadOnlyDirectory, storage::StorageManager};
|
||||
use tracing::instrument;
|
||||
use bitwarden_akd_configuration::BitwardenV1Configuration;
|
||||
use akd_storage::DatabaseType;
|
||||
use common::VrfStorageType;
|
||||
|
||||
struct AppState {
|
||||
// Add any shared state here, e.g., database connections
|
||||
directory: ReadOnlyDirectory<BitwardenV1Configuration, DatabaseType, VrfStorageType>,
|
||||
}
|
||||
|
||||
#[instrument(skip_all, name = "reader_start")]
|
||||
pub async fn start(db: DatabaseType, vrf: VrfStorageType) {
|
||||
let storage_manager = StorageManager::new_no_cache(db);
|
||||
let _app = AppState {
|
||||
directory: ReadOnlyDirectory::new(storage_manager, vrf).await.unwrap(),
|
||||
};
|
||||
println!("Reader started");
|
||||
}
|
||||
40
akd/crates/reader/src/main.rs
Normal file
40
akd/crates/reader/src/main.rs
Normal file
@ -0,0 +1,40 @@
|
||||
//! The Reader crate is responsible for handling read requests to the AKD. It requires only read permissions to the
|
||||
//! underlying data stores, and can be horizontally scaled as needed.
|
||||
|
||||
use akd::ecvrf::VRFKeyStorage;
|
||||
use akd_storage::db_config::DbConfig;
|
||||
use common::VrfStorageType;
|
||||
use reader::start;
|
||||
use tracing::info;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.init();
|
||||
|
||||
// Read connection string from env var
|
||||
let connection_string = std::env::var("AKD_MSSQL_CONNECTION_STRING")
|
||||
.expect("AKD_MSSQL_CONNECTION_STRING must be set.");
|
||||
let db_config = DbConfig::MsSql {
|
||||
connection_string,
|
||||
pool_size: 10,
|
||||
};
|
||||
|
||||
let db = db_config
|
||||
.connect()
|
||||
.await
|
||||
.expect("Failed to connect to database");
|
||||
let vrf = VrfStorageType::HardCodedAkdVRF;
|
||||
|
||||
let web_server_handle = tokio::spawn(async move {
|
||||
start(db, vrf).await;
|
||||
});
|
||||
|
||||
// Wait for both services to complete
|
||||
tokio::select! {
|
||||
_ = web_server_handle => {
|
||||
info!("Web service completed");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user