Skip to content

Commit

Permalink
aw-server: Implement swagger for some endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
johan-bjareholt committed Aug 11, 2020
1 parent 5c68853 commit fddb609
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 18 deletions.
89 changes: 89 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions aw-client-rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
extern crate aw_models;
extern crate gethostname;
extern crate reqwest;
#[macro_use]
extern crate aw_models;
extern crate serde_json;

use std::collections::HashMap;
Expand Down
3 changes: 3 additions & 0 deletions aw-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ toml = "0.5"
gethostname = "0.2"
uuid = { version = "0.8", features = ["serde", "v4"] }
getopts = "0.2"
rocket_okapi = "0.5"
schemars = "0.7"
okapi = { version = "0.4", features = ["derive_json_schema"] }

aw-datastore = { path = "../aw-datastore" }
aw-models = { path = "../aw-models" }
Expand Down
22 changes: 17 additions & 5 deletions aw-server/src/endpoints/bucket.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::io::Cursor;

use rocket_contrib::json::Json;

Expand All @@ -10,13 +9,13 @@ use aw_models::Bucket;
use aw_models::BucketsExport;
use aw_models::Event;

use rocket::http::Header;
use rocket::http::Status;
use rocket::response::Response;
use rocket::State;
use rocket_okapi::openapi;

use crate::endpoints::{HttpErrorJson, ServerState};

#[openapi]
#[get("/")]
pub fn buckets_get(
state: State<ServerState>,
Expand All @@ -28,6 +27,7 @@ pub fn buckets_get(
}
}

#[openapi]
#[get("/<bucket_id>")]
pub fn bucket_get(
bucket_id: String,
Expand All @@ -40,6 +40,7 @@ pub fn bucket_get(
}
}

#[openapi]
#[post("/<bucket_id>", data = "<message>", format = "application/json")]
pub fn bucket_new(
bucket_id: String,
Expand All @@ -58,6 +59,7 @@ pub fn bucket_new(
}
}

#[openapi]
#[get("/<bucket_id>/events?<start>&<end>&<limit>")]
pub fn bucket_events_get(
bucket_id: String,
Expand Down Expand Up @@ -102,6 +104,7 @@ pub fn bucket_events_get(
}
}

#[openapi]
#[post("/<bucket_id>/events", data = "<events>", format = "application/json")]
pub fn bucket_events_create(
bucket_id: String,
Expand All @@ -116,6 +119,7 @@ pub fn bucket_events_create(
}
}

#[openapi]
#[post(
"/<bucket_id>/heartbeat?<pulsetime>",
data = "<heartbeat_json>",
Expand All @@ -135,6 +139,7 @@ pub fn bucket_events_heartbeat(
}
}

#[openapi]
#[get("/<bucket_id>/events/count")]
pub fn bucket_event_count(
bucket_id: String,
Expand All @@ -148,6 +153,7 @@ pub fn bucket_event_count(
}
}

#[openapi]
#[delete("/<bucket_id>/events/<event_id>")]
pub fn bucket_events_delete_by_id(
bucket_id: String,
Expand All @@ -161,11 +167,12 @@ pub fn bucket_events_delete_by_id(
}
}

#[openapi]
#[get("/<bucket_id>/export")]
pub fn bucket_export(
bucket_id: String,
state: State<ServerState>,
) -> Result<Response, HttpErrorJson> {
) -> Result<Json<BucketsExport>, HttpErrorJson> {
let datastore = endpoints_get_lock!(state.datastore);
let mut export = BucketsExport {
buckets: HashMap::new(),
Expand All @@ -180,8 +187,10 @@ pub fn bucket_export(
.expect("Failed to get events for bucket"),
);
export.buckets.insert(bucket_id.clone(), bucket);
let filename = format!("aw-bucket-export_{}.json", bucket_id);

// TODO: Add back Content-Disposition
/*
let filename = format!("aw-bucket-export_{}.json", bucket_id);
let header_content = format!("attachment; filename={}", filename);
Ok(Response::build()
.status(Status::Ok)
Expand All @@ -190,8 +199,11 @@ pub fn bucket_export(
serde_json::to_string(&export).expect("Failed to serialize"),
))
.finalize())
*/
Ok(Json(export))
}

#[openapi]
#[delete("/<bucket_id>")]
pub fn bucket_delete(bucket_id: String, state: State<ServerState>) -> Result<(), HttpErrorJson> {
let datastore = endpoints_get_lock!(state.datastore);
Expand Down
11 changes: 7 additions & 4 deletions aw-server/src/endpoints/export.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use std::collections::HashMap;
use std::io::Cursor;

use rocket::http::Header;
use rocket::http::Status;
use rocket::response::Response;
use rocket::State;
use rocket_contrib::json::Json;
use rocket_okapi::openapi;

use aw_models::BucketsExport;

use crate::endpoints::{HttpErrorJson, ServerState};

#[openapi]
#[get("/")]
pub fn buckets_export(state: State<ServerState>) -> Result<Response, HttpErrorJson> {
pub fn buckets_export(state: State<ServerState>) -> Result<Json<BucketsExport>, HttpErrorJson> {
let datastore = endpoints_get_lock!(state.datastore);
let mut export = BucketsExport {
buckets: HashMap::new(),
Expand All @@ -28,6 +28,7 @@ pub fn buckets_export(state: State<ServerState>) -> Result<Response, HttpErrorJs
export.buckets.insert(bid, bucket);
}

/*
Ok(Response::build()
.status(Status::Ok)
.header(Header::new(
Expand All @@ -38,4 +39,6 @@ pub fn buckets_export(state: State<ServerState>) -> Result<Response, HttpErrorJs
serde_json::to_string(&export).expect("Failed to serialize"),
))
.finalize())
*/
Ok(Json(export))
}
3 changes: 1 addition & 2 deletions aw-server/src/endpoints/import.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use multipart::server::Multipart;
use rocket::http::ContentType;
use rocket::http::Status;
use rocket::Data;
use rocket::State;
use rocket_contrib::json::Json;

use multipart::server::Multipart;

use std::io::Read;
use std::sync::Mutex;

Expand Down
28 changes: 25 additions & 3 deletions aw-server/src/endpoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ use std::path::PathBuf;
use std::sync::Mutex;

use gethostname::gethostname;
use rocket::get;
use rocket::response::NamedFile;
use rocket::State;
use rocket_contrib::json::Json;
use rocket_okapi::swagger_ui::{make_swagger_ui, SwaggerUIConfig};
use rocket_okapi::{openapi, routes_with_openapi};

use crate::config::AWConfig;

Expand Down Expand Up @@ -58,6 +61,7 @@ fn root_favicon(state: State<ServerState>) -> Option<NamedFile> {
NamedFile::open(state.asset_path.join("favicon.ico")).ok()
}

#[openapi]
#[get("/")]
fn server_info(config: State<AWConfig>, state: State<ServerState>) -> Json<Info> {
#[allow(clippy::or_fun_call)]
Expand All @@ -72,6 +76,20 @@ fn server_info(config: State<AWConfig>, state: State<ServerState>) -> Json<Info>
})
}

fn get_docs() -> SwaggerUIConfig {
use rocket_okapi::swagger_ui::UrlObject;

SwaggerUIConfig {
url: "/info/openapi.json".to_string(),
urls: vec![
UrlObject::new("Info", "/api/0/info/openapi.json"),
UrlObject::new("Bucket", "/api/0/buckets/openapi.json"),
UrlObject::new("Export", "/api/0/export/openapi.json"),
],
..Default::default()
}
}

pub fn build_rocket(server_state: ServerState, config: AWConfig) -> rocket::Rocket {
info!(
"Starting aw-server-rust at {}:{}",
Expand All @@ -89,10 +107,10 @@ pub fn build_rocket(server_state: ServerState, config: AWConfig) -> rocket::Rock
root_static,
],
)
.mount("/api/0/info", routes![server_info])
.mount("/api/0/info", routes_with_openapi![server_info])
.mount(
"/api/0/buckets",
routes![
routes_with_openapi![
bucket::bucket_new,
bucket::bucket_delete,
bucket::buckets_get,
Expand All @@ -110,7 +128,10 @@ pub fn build_rocket(server_state: ServerState, config: AWConfig) -> rocket::Rock
"/api/0/import",
routes![import::bucket_import_json, import::bucket_import_form],
)
.mount("/api/0/export", routes![export::buckets_export])
.mount(
"/api/0/export",
routes_with_openapi![export::buckets_export],
)
.mount(
"/api/0/settings",
routes![
Expand All @@ -120,6 +141,7 @@ pub fn build_rocket(server_state: ServerState, config: AWConfig) -> rocket::Rock
settings::setting_delete
],
)
.mount("/api", make_swagger_ui(&get_docs()))
.attach(cors::cors(&config))
.manage(server_state)
.manage(config)
Expand Down
Loading

0 comments on commit fddb609

Please sign in to comment.