Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/catalog/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod service;
pub mod repository;
pub mod error;
pub mod models;
pub mod error;
pub mod repository;
pub mod service;
1 change: 0 additions & 1 deletion crates/control_plane/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ pub mod repository; // This will expose everything inside repository.rs
pub mod service; // This will expose everything inside service.rs

pub mod error;

3 changes: 3 additions & 0 deletions crates/nexus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ utils = { path = "../utils" }
utoipa = { workspace = true }
utoipa-axum = { workspace = true }
utoipa-swagger-ui = { workspace = true }
swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] }
validator = { version = "0.18.1", features = ["derive"] }
thiserror = { version = "1.0.63" }

[dev-dependencies]
tower = { workspace = true }
Expand Down
23 changes: 17 additions & 6 deletions crates/nexus/src/http/control/handlers/storage_profiles.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
use crate::http::control::schemas::storage_profiles::{
AwsAccessKeyCredential, AwsRoleCredential, CloudProvider, CreateStorageProfilePayload, Credentials, StorageProfile
AwsAccessKeyCredential, AwsRoleCredential, CloudProvider, CreateStorageProfilePayload,
Credentials, StorageProfile,
};
use axum::{extract::Path, extract::State, Json};
use control_plane::models::{StorageProfile as StorageProfileModel, StorageProfileCreateRequest};
use std::result::Result;
use uuid::Uuid;
use utoipa::OpenApi;
use uuid::Uuid;

use crate::error::AppError;
use crate::state::AppState;


#[derive(OpenApi)]
#[openapi(
paths(create_storage_profile, get_storage_profile, delete_storage_profile, list_storage_profiles,),
components(schemas(CreateStorageProfilePayload, StorageProfile, Credentials, AwsAccessKeyCredential, AwsRoleCredential, CloudProvider),)
paths(
create_storage_profile,
get_storage_profile,
delete_storage_profile,
list_storage_profiles,
),
components(schemas(
CreateStorageProfilePayload,
StorageProfile,
Credentials,
AwsAccessKeyCredential,
AwsRoleCredential,
CloudProvider
),)
)]
pub struct StorageProfileApi;


#[utoipa::path(
post,
operation_id = "createStorageProfile",
Expand Down
7 changes: 2 additions & 5 deletions crates/nexus/src/http/control/handlers/warehouses.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::http::control::schemas::warehouses::{
CreateWarehouseRequest, Warehouse,
};
use crate::http::control::schemas::warehouses::{CreateWarehouseRequest, Warehouse};
use axum::{extract::Path, extract::State, Json};
use control_plane::models::{Warehouse as WarehouseModel, WarehouseCreateRequest};
use std::result::Result;
Expand All @@ -10,7 +8,6 @@ use uuid::Uuid;
use crate::error::AppError;
use crate::state::AppState;


// #[derive(OpenApi)]
// #[openapi(
// paths(create_storage_profile, get_storage_profile, delete_storage_profile, list_storage_profiles,),
Expand All @@ -21,7 +18,7 @@ use crate::state::AppState;
#[derive(OpenApi)]
#[openapi(
paths(create_warehouse, get_warehouse, delete_warehouse, list_warehouses,),
components(schemas(CreateWarehouseRequest, Warehouse, ),)
components(schemas(CreateWarehouseRequest, Warehouse,),)
)]
pub struct WarehouseApi;

Expand Down
5 changes: 5 additions & 0 deletions crates/nexus/src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ pub mod control {
pub mod handlers;
pub mod schemas;
}
pub mod ui {
pub mod handlers;
pub mod models;
pub mod models;
}
34 changes: 18 additions & 16 deletions crates/nexus/src/http/router.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use axum::extract::Path;
use axum::{routing::delete, routing::get, routing::post, Router};
use std::collections::HashMap;
use axum::Router;
use std::fs;
use utoipa::openapi::{self, OpenApiBuilder};
use utoipa::openapi::{self};
use utoipa::{
openapi::security::{ApiKey, ApiKeyValue, SecurityScheme},
Modify, OpenApi,
};
use utoipa_swagger_ui::SwaggerUi;
Expand All @@ -13,6 +10,11 @@ use crate::http::catalog::router::create_router as create_catalog_router;
use crate::http::control::handlers::storage_profiles::StorageProfileApi;
use crate::http::control::handlers::warehouses::WarehouseApi;
use crate::http::control::router::create_router as create_control_router;
use crate::http::ui::handlers::databases::ApiDoc as DatabaseApiDoc;
use crate::http::ui::handlers::profiles::ApiDoc as ProfileApiDoc;
use crate::http::ui::handlers::tables::ApiDoc as TableApiDoc;
use crate::http::ui::handlers::warehouses::ApiDoc as WarehouseApiDoc;
use crate::http::ui::router::create_router as create_ui_router;
use crate::state::AppState;

#[derive(OpenApi)]
Expand All @@ -24,21 +26,28 @@ use crate::state::AppState;
tags(
(name = "storage-profile", description = "Storage profile API"),
(name = "warehouse", description = "Warehouse API"),
(name = "ui", description = "Web UI API"),
)
)]
struct ApiDoc;
pub struct ApiDoc;

pub fn create_app(state: AppState) -> Router {
let mut spec = ApiDoc::openapi();
if let Some(extra_spec) = load_openapi_spec() {
spec = spec.merge_from(extra_spec);
spec = spec.merge_from(extra_spec)
.merge_from(WarehouseApiDoc::openapi())
.merge_from(TableApiDoc::openapi())
.merge_from(DatabaseApiDoc::openapi())
.merge_from(ProfileApiDoc::openapi());
}
let catalog_router = create_catalog_router();
let control_router = create_control_router();
let ui_router = create_ui_router();

Router::new()
.nest("/", control_router)
.nest("/catalog", catalog_router)
.nest("/ui", ui_router)
.merge(SwaggerUi::new("/").url("/openapi.yaml", spec))
.with_state(state)
}
Expand All @@ -56,26 +65,20 @@ mod tests {
#![allow(clippy::too_many_lines)]

use crate::http::catalog::schemas::Namespace as NamespaceSchema;
use crate::http::control;
use crate::http::control::schemas::storage_profiles::StorageProfile as StorageProfileSchema;
use crate::http::control::schemas::warehouses::Warehouse as WarehouseSchema;

use super::*;
use async_trait::async_trait;
use axum::http::request;
use axum::{
body::Body,
http::{self, Request, StatusCode},
};
use catalog::repository::{DatabaseRepositoryDb, TableRepositoryDb};
use catalog::service::CatalogImpl;
use control_plane::error::{Error, Result};
use control_plane::models::{StorageProfile, StorageProfileCreateRequest};
use control_plane::models::{Warehouse, WarehouseCreateRequest};
use control_plane::repository::{StorageProfileRepositoryDb, WarehouseRepositoryDb};
use control_plane::service::ControlService;
use control_plane::service::ControlServiceImpl;
use http_body_util::BodyExt; // for `collect`
use http_body_util::BodyExt;
// for `collect`
use object_store::{memory::InMemory, path::Path, ObjectStore};
use serde_json::json;
use slatedb::config::DbOptions;
Expand All @@ -84,7 +87,6 @@ mod tests {
use tempfile::TempDir;
use tower::{Service, ServiceExt};
use utils::Db;
use uuid::Uuid;

lazy_static::lazy_static! {
static ref TEMP_DIR: TempDir = TempDir::new().unwrap();
Expand Down
128 changes: 128 additions & 0 deletions crates/nexus/src/http/ui/handlers/databases.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use crate::error::AppError;
use crate::http::ui::models::aws;
use crate::http::ui::models::database;
use crate::http::ui::models::storage_profile;
use crate::http::ui::models::table::Statistics;
use crate::http::ui::models::warehouse;
use crate::state::AppState;
use axum::{extract::Path, extract::State, Json};
use swagger;
use utoipa::OpenApi;
use uuid::Uuid;

#[derive(OpenApi)]
#[openapi(
paths(
create_database,
delete_database,
get_database,
),
components(
schemas(
database::CreateDatabasePayload,
database::Database
)
),
tags(
(name = "Databases", description = "Databases management endpoints.")
)
)]
pub struct ApiDoc;

#[utoipa::path(
post,
path = "/ui/warehouses/{warehouseId}/databases",
operation_id = "webCreateDatabase",
responses(
(status = 200, description = "Successful Response", body = database::Database),
(status = 400, description = "Bad request"),
(status = 500, description = "Internal server error")
)
)]
pub async fn create_database(
State(state): State<AppState>,
Path(payload): Path<database::CreateDatabasePayload>,
) -> Result<Json<database::Database>, AppError> {
Ok(Json(database::Database {
name: "".to_string(),
properties: None,
id: Default::default(),
warehouse_id: Default::default(),
}))
}

#[utoipa::path(
delete,
path = "/ui/warehouses/{warehouseId}/databases/{databaseName}",
operation_id = "webDeleteDatabase",
responses(
(status = 204, description = "Successful Response"),
(status = 404, description = "Database not found")
)
)]
pub async fn delete_database(
State(state): State<AppState>,
Path((warehouse_id, database_name)): Path<(Uuid, String)>,
) -> Result<(), AppError> {
Ok(())
}

#[utoipa::path(
get,
path = "/ui/warehouses/{warehouseId}/databases/{databaseName}",
operation_id = "webDatabaseDashboard",
responses(
(status = 200, description = "Successful Response", body = database::DatabaseDashboard),
(status = 204, description = "Successful Response"),
(status = 404, description = "Database not found")
)
)]
pub async fn get_database(
State(state): State<AppState>,
Path((warehouse_id, database_name)): Path<(Uuid, String)>,
) -> Result<Json<database::DatabaseDashboard>, AppError> {
Ok(Json(database::DatabaseDashboard {
name: "".to_string(),
properties: None,
id: Default::default(),
warehouse_id: Default::default(),
warehouse: warehouse::WarehouseEntity {
name: "".to_string(),
storage_profile_id: Default::default(),
key_prefix: "".to_string(),
id: Default::default(),
external_id: Default::default(),
location: "".to_string(),
created_at: Default::default(),
updated_at: Default::default(),
storage_profile: storage_profile::StorageProfile {
r#type: aws::CloudProvider::S3,
region: "".to_string(),
bucket: "".to_string(),
credentials: Default::default(),
sts_role_arn: None,
endpoint: None,
id: Default::default(),
created_at: Default::default(),
updated_at: Default::default(),
},
},
tables: vec![],
statistics: Statistics {
commit_count: 0,
op_append_count: 0,
op_overwrite_count: 0,
op_delete_count: 0,
op_replace_count: 0,
total_bytes: 0,
bytes_added: 0,
bytes_removed: 0,
total_rows: 0,
rows_added: 0,
rows_deleted: 0,
table_count: None,
database_count: None,
},
compaction_summary: None,
}))
}
4 changes: 4 additions & 0 deletions crates/nexus/src/http/ui/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod databases;
pub mod profiles;
pub mod tables;
pub mod warehouses;
Loading