From 472c151e43b68171f9467499b60e9f5024b7261f Mon Sep 17 00:00:00 2001 From: Kyle Willmon Date: Wed, 11 May 2022 11:08:36 -0500 Subject: [PATCH] Refactor endpoints URL functions (#367) This patch combines job.rs, project.rs, and common.rs into one file, endpoints.rs, so that we can see all of the API URLs in one location. It also removes a bit of unused code. --- cli/src/api/common.rs | 1 - cli/src/api/endpoints.rs | 64 +++++++++++++++++++++++++++++++++ cli/src/api/job.rs | 52 --------------------------- cli/src/api/mod.rs | 70 ++++++++---------------------------- cli/src/api/project.rs | 9 ----- cli/src/api/user_settings.rs | 10 ------ cli/src/bin/phylum.rs | 16 --------- 7 files changed, 79 insertions(+), 143 deletions(-) delete mode 100644 cli/src/api/common.rs create mode 100644 cli/src/api/endpoints.rs delete mode 100644 cli/src/api/job.rs delete mode 100644 cli/src/api/project.rs delete mode 100644 cli/src/api/user_settings.rs diff --git a/cli/src/api/common.rs b/cli/src/api/common.rs deleted file mode 100644 index 926fbcf7f..000000000 --- a/cli/src/api/common.rs +++ /dev/null @@ -1 +0,0 @@ -pub const API_PATH: &str = "api/v0"; diff --git a/cli/src/api/endpoints.rs b/cli/src/api/endpoints.rs new file mode 100644 index 000000000..c6b70c369 --- /dev/null +++ b/cli/src/api/endpoints.rs @@ -0,0 +1,64 @@ +/// API endpoint paths +use super::{JobId, PackageDescriptor}; + +const API_PATH: &str = "api/v0"; + +/// PUT /job +pub fn put_submit_package(api_uri: &str) -> String { + format!("{api_uri}/{API_PATH}/job") +} + +/// GET /job/heartbeat +pub fn get_ping(api_uri: &str) -> String { + format!("{api_uri}/{API_PATH}/job/heartbeat") +} + +/// GET /job/ +pub fn get_all_jobs_status(api_uri: &str, limit: u32) -> String { + format!("{api_uri}/{API_PATH}/job/?limit={limit}&verbose=1") +} + +/// GET /job/ +pub fn get_job_status(api_uri: &str, job_id: &JobId, verbose: bool) -> String { + if verbose { + format!("{api_uri}/{API_PATH}/job/{job_id}?verbose=True") + } else { + format!("{api_uri}/{API_PATH}/job/{job_id}") + } +} + +/// GET /job/packages/// +pub fn get_package_status(api_uri: &str, pkg: &PackageDescriptor) -> String { + let name_escaped = pkg.name.replace('/', "~"); + let PackageDescriptor { + package_type, + version, + .. + } = pkg; + format!("{api_uri}/{API_PATH}/job/packages/{package_type}/{name_escaped}/{version}") +} + +/// GET /job/projects/name/ +pub fn get_project_details(api_uri: &str, pkg_id: &str) -> String { + format!("{api_uri}/{API_PATH}/job/projects/name/{pkg_id}") +} + +/// GET /job/projects/overview +pub fn get_project_summary(api_uri: &str) -> String { + format!("{api_uri}/{API_PATH}/job/projects/overview") +} + +/// PUT /job/projects +pub fn put_create_project(api_uri: &str) -> String { + format!("{api_uri}/{API_PATH}/job/projects") +} + +/// GET /settings/current-user +pub(crate) fn get_user_settings(api_uri: &str) -> String { + format!("{api_uri}/{API_PATH}/settings/current-user") +} + +/// PUT /settings/current-user +pub(crate) fn put_user_settings(api_uri: &str) -> String { + format!("{api_uri}/{API_PATH}/settings/current-user") +} diff --git a/cli/src/api/job.rs b/cli/src/api/job.rs deleted file mode 100644 index 89bf4d848..000000000 --- a/cli/src/api/job.rs +++ /dev/null @@ -1,52 +0,0 @@ -use super::common::API_PATH; -use super::{JobId, PackageDescriptor}; - -/// PUT /job -pub(crate) fn put_submit_package(api_uri: &str) -> String { - format!("{api_uri}/{API_PATH}/job") -} - -/// GET /job/auth_status -pub(crate) fn get_auth_status(api_uri: &str) -> String { - format!("{api_uri}/{API_PATH}/job/auth_status") -} - -/// GET /job/heartbeat -// TODO Deprecate -pub(crate) fn get_ping(api_uri: &str) -> String { - format!("{api_uri}/{API_PATH}/job/heartbeat") -} - -/// GET /job/ -pub(crate) fn get_all_jobs_status(api_uri: &str, limit: u32) -> String { - format!("{api_uri}/{API_PATH}/job/?limit={limit}&verbose=1") -} - -/// Get /job/ -pub(crate) fn get_job_status(api_uri: &str, job_id: &JobId, verbose: bool) -> String { - if verbose { - format!("{api_uri}/{API_PATH}/job/{job_id}?verbose=True") - } else { - format!("{api_uri}/{API_PATH}/job/{job_id}") - } -} - -/// DELETE /request/packages/ -pub(crate) fn delete_job(api_uri: &str, job_id: &JobId) -> String { - format!("{api_uri}/{API_PATH}/job/{job_id}") -} - -/// GET /job/packages/// -pub(crate) fn get_package_status(api_uri: &str, pkg: &PackageDescriptor) -> String { - let name_escaped = pkg.name.replace('/', "~"); - let PackageDescriptor { - package_type, - version, - .. - } = pkg; - format!("{api_uri}/{API_PATH}/job/packages/{package_type}/{name_escaped}/{version}") -} - -pub(crate) fn get_project_details(api_uri: &str, pkg_id: &str) -> String { - format!("{api_uri}/{API_PATH}/job/projects/name/{pkg_id}") -} diff --git a/cli/src/api/mod.rs b/cli/src/api/mod.rs index 6591017b0..4fdd6a89c 100644 --- a/cli/src/api/mod.rs +++ b/cli/src/api/mod.rs @@ -16,17 +16,13 @@ use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use thiserror::Error as ThisError; -mod common; -mod job; -mod project; -mod user_settings; +mod endpoints; use crate::auth::fetch_oidc_server_settings; use crate::auth::handle_auth_flow; use crate::auth::handle_refresh_tokens; use crate::auth::{AuthAction, UserInfo}; use crate::config::AuthInfo; -use crate::types::AuthStatusResponse; use crate::types::PingResponse; type Result = std::result::Result; @@ -73,10 +69,6 @@ impl PhylumApi { self.send_request(Method::PUT, path, Some(s)).await } - async fn delete(&self, path: String) -> Result { - self.send_request::<_, ()>(Method::DELETE, path, None).await - } - async fn send_request( &self, method: Method, @@ -171,19 +163,11 @@ impl PhylumApi { /// Ping the system and verify it's up pub async fn ping(&mut self) -> Result { Ok(self - .get::(job::get_ping(&self.api_uri)) + .get::(endpoints::get_ping(&self.api_uri)) .await? .msg) } - /// Check auth status of the current user - pub async fn auth_status(&mut self) -> Result { - Ok(self - .get::(job::get_auth_status(&self.api_uri)) - .await? - .authenticated) - } - /// Get information about the authenticated user pub async fn user_info(&self, auth_info: &AuthInfo) -> Result { let oidc_settings = fetch_oidc_server_settings(auth_info).await?; @@ -194,7 +178,7 @@ impl PhylumApi { pub async fn create_project(&mut self, name: &str) -> Result { Ok(self .put::( - project::put_create_project(&self.api_uri), + endpoints::put_create_project(&self.api_uri), CreateProjectRequest { name: name.to_string(), group_name: None, @@ -206,19 +190,19 @@ impl PhylumApi { /// Get a list of projects pub async fn get_projects(&mut self) -> Result> { - self.get(project::get_project_summary(&self.api_uri)).await + self.get(endpoints::get_project_summary(&self.api_uri)) + .await } /// Get user settings pub async fn get_user_settings(&mut self) -> Result { - self.get(user_settings::get_user_settings(&self.api_uri)) - .await + self.get(endpoints::get_user_settings(&self.api_uri)).await } /// Put updated user settings pub async fn put_user_settings(&mut self, settings: &UserSettings) -> Result { self.client - .put(user_settings::put_user_settings(&self.api_uri)) + .put(endpoints::put_user_settings(&self.api_uri)) .json(&settings) .send() .await? @@ -245,7 +229,7 @@ impl PhylumApi { }; log::debug!("==> Sending package submission: {:?}", req); let resp: SubmitPackageResponse = self - .put(job::put_submit_package(&self.api_uri), req) + .put(endpoints::put_submit_package(&self.api_uri), req) .await?; Ok(resp.job_id) } @@ -255,7 +239,7 @@ impl PhylumApi { &mut self, job_id: &JobId, ) -> Result> { - self.get(job::get_job_status(&self.api_uri, job_id, false)) + self.get(endpoints::get_job_status(&self.api_uri, job_id, false)) .await } @@ -264,13 +248,14 @@ impl PhylumApi { &mut self, job_id: &JobId, ) -> Result> { - self.get(job::get_job_status(&self.api_uri, job_id, true)) + self.get(endpoints::get_job_status(&self.api_uri, job_id, true)) .await } /// Get the status of all jobs pub async fn get_status(&mut self) -> Result { - self.get(job::get_all_jobs_status(&self.api_uri, 30)).await + self.get(endpoints::get_all_jobs_status(&self.api_uri, 30)) + .await } /// Get the details of a specific project @@ -278,7 +263,7 @@ impl PhylumApi { &mut self, project_name: &str, ) -> Result { - self.get(job::get_project_details(&self.api_uri, project_name)) + self.get(endpoints::get_project_details(&self.api_uri, project_name)) .await } @@ -287,12 +272,8 @@ impl PhylumApi { &mut self, pkg: &PackageDescriptor, ) -> Result { - self.get(job::get_package_status(&self.api_uri, pkg)).await - } - - /// Cancel a job currently in progress - pub async fn cancel(&mut self, job_id: &JobId) -> Result { - self.delete(job::delete_job(&self.api_uri, job_id)).await + self.get(endpoints::get_package_status(&self.api_uri, pkg)) + .await } } @@ -655,27 +636,6 @@ mod tests { Ok(()) } - #[tokio::test] - async fn cancel() -> Result<()> { - let body = r#"{"msg": "Job deleted"}"#; - - let mock_server = build_mock_server().await; - Mock::given(method("DELETE")) - .and(path_regex( - r"^/api/v0/job/[-\dabcdef]+$".to_string().to_string(), - )) - .respond_with_fn(move |_| ResponseTemplate::new(200).set_body_string(body)) - .mount(&mock_server) - .await; - - let mut client = build_phylum_api(&mock_server).await?; - - let job = JobId::from_str("59482a54-423b-448d-8325-f171c9dc336b").unwrap(); - client.cancel(&job).await?; - - Ok(()) - } - #[tokio::test] async fn user_info() -> Result<()> { let body = r#" diff --git a/cli/src/api/project.rs b/cli/src/api/project.rs deleted file mode 100644 index e50ecdd4f..000000000 --- a/cli/src/api/project.rs +++ /dev/null @@ -1,9 +0,0 @@ -use super::common::API_PATH; - -pub(crate) fn get_project_summary(api_uri: &str) -> String { - format!("{api_uri}/{API_PATH}/job/projects/overview") -} - -pub(crate) fn put_create_project(api_uri: &str) -> String { - format!("{api_uri}/{API_PATH}/job/projects") -} diff --git a/cli/src/api/user_settings.rs b/cli/src/api/user_settings.rs deleted file mode 100644 index 8bd219ac0..000000000 --- a/cli/src/api/user_settings.rs +++ /dev/null @@ -1,10 +0,0 @@ -use super::common::API_PATH; - -pub(crate) fn get_user_settings(api_uri: &str) -> String { - format!("{api_uri}/{API_PATH}/settings/current-user") -} - -/// PUT /settings/current-user -pub(crate) fn put_user_settings(api_uri: &str) -> String { - format!("{api_uri}/{API_PATH}/settings/current-user") -} diff --git a/cli/src/bin/phylum.rs b/cli/src/bin/phylum.rs index 2cab74d5a..099a25f88 100644 --- a/cli/src/bin/phylum.rs +++ b/cli/src/bin/phylum.rs @@ -1,6 +1,5 @@ use std::path::PathBuf; use std::process; -use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; use anyhow::{anyhow, Context}; @@ -21,7 +20,6 @@ use phylum_cli::config::*; use phylum_cli::print::*; use phylum_cli::update; use phylum_cli::{print_user_failure, print_user_success, print_user_warning}; -use phylum_types::types::common::JobId; use phylum_types::types::job::Action; /// Print a warning message to the user before exiting with exit code 0. @@ -194,12 +192,6 @@ async fn handle_commands() -> CommandResult { let should_submit = matches.subcommand_matches("analyze").is_some() || matches.subcommand_matches("batch").is_some(); - // TODO this panicks with the type-checked `App` since the "cancel" - // subcommand is undefined. Is the backend feature implemented, or - // should we just keep this short circuited for now? - let should_cancel = false; - // let should_cancel = matches.subcommand_matches("cancel").is_some(); - // TODO: switch from if/else to non-exhaustive pattern match if let Some(matches) = matches.subcommand_matches("project") { handle_project(&mut api, matches).await?; @@ -209,14 +201,6 @@ async fn handle_commands() -> CommandResult { return handle_submission(&mut api, config, &matches).await; } else if let Some(matches) = matches.subcommand_matches("history") { return handle_history(&mut api, matches).await; - } else if should_cancel { - if let Some(matches) = matches.subcommand_matches("cancel") { - let request_id = matches.value_of("request_id").unwrap().to_string(); - let request_id = JobId::from_str(&request_id) - .context("Received invalid request id. Request id's should be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")?; - let resp = api.cancel(&request_id).await; - print_response(&resp, true, None); - } } Ok(ExitCode::Ok.into())