From cfadb042310a8cf4cc36731addf6479831d4787b Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Mon, 28 Jun 2021 14:16:50 -0500 Subject: [PATCH] chore: refactor subgraph delete (#639) --- Cargo.lock | 4 +- .../delete_mutation.graphql} | 10 ++-- .../src/query/subgraph/delete/mod.rs | 6 ++ .../{delete.rs => delete/mutation_runner.rs} | 57 ++++++++----------- .../src/query/subgraph/delete/types.rs | 36 ++++++++++++ src/command/subgraph/delete.rs | 24 ++++---- 6 files changed, 84 insertions(+), 53 deletions(-) rename crates/rover-client/src/query/subgraph/{delete.graphql => delete/delete_mutation.graphql} (63%) create mode 100644 crates/rover-client/src/query/subgraph/delete/mod.rs rename crates/rover-client/src/query/subgraph/{delete.rs => delete/mutation_runner.rs} (65%) create mode 100644 crates/rover-client/src/query/subgraph/delete/types.rs diff --git a/Cargo.lock b/Cargo.lock index bc569286d5..6cd42ecabc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1452,9 +1452,9 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "online" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfdf6b557e681481348e9aaafe70d83a9fc41c4cbeed3f1073a19301574466b" +checksum = "7680985bd550795c0161707f51f9abada87c63a5409114ed818a8618d18ec5e5" [[package]] name = "opaque-debug" diff --git a/crates/rover-client/src/query/subgraph/delete.graphql b/crates/rover-client/src/query/subgraph/delete/delete_mutation.graphql similarity index 63% rename from crates/rover-client/src/query/subgraph/delete.graphql rename to crates/rover-client/src/query/subgraph/delete/delete_mutation.graphql index 0b6cf25a5d..f9ba68241d 100644 --- a/crates/rover-client/src/query/subgraph/delete.graphql +++ b/crates/rover-client/src/query/subgraph/delete/delete_mutation.graphql @@ -1,13 +1,13 @@ -mutation DeleteServiceMutation( +mutation SubgraphDeleteMutation( $graphId: ID! - $graphVariant: String! - $name: String! + $variant: String! + $subgraph: String! $dryRun: Boolean! ) { service(id: $graphId) { removeImplementingServiceAndTriggerComposition( - graphVariant: $graphVariant - name: $name + graphVariant: $variant + name: $subgraph dryRun: $dryRun ) { errors { diff --git a/crates/rover-client/src/query/subgraph/delete/mod.rs b/crates/rover-client/src/query/subgraph/delete/mod.rs new file mode 100644 index 0000000000..788f96dd6d --- /dev/null +++ b/crates/rover-client/src/query/subgraph/delete/mod.rs @@ -0,0 +1,6 @@ +mod mutation_runner; + +pub(crate) mod types; + +pub use mutation_runner::run; +pub use types::{SubgraphDeleteInput, SubgraphDeleteResponse}; diff --git a/crates/rover-client/src/query/subgraph/delete.rs b/crates/rover-client/src/query/subgraph/delete/mutation_runner.rs similarity index 65% rename from crates/rover-client/src/query/subgraph/delete.rs rename to crates/rover-client/src/query/subgraph/delete/mutation_runner.rs index 7e735b2ea6..f9ddddde0a 100644 --- a/crates/rover-client/src/query/subgraph/delete.rs +++ b/crates/rover-client/src/query/subgraph/delete/mutation_runner.rs @@ -1,48 +1,39 @@ use crate::blocking::StudioClient; +use crate::query::subgraph::delete::types::*; use crate::RoverClientError; + use graphql_client::*; #[derive(GraphQLQuery)] // The paths are relative to the directory where your `Cargo.toml` is located. // Both json and the GraphQL schema language are supported as sources for the schema #[graphql( - query_path = "src/query/subgraph/delete.graphql", + query_path = "src/query/subgraph/delete/delete_mutation.graphql", schema_path = ".schema/schema.graphql", response_derives = "PartialEq, Debug, Serialize, Deserialize", deprecated = "warn" )] /// This struct is used to generate the module containing `Variables` and /// `ResponseData` structs. -/// Snake case of this name is the mod name. i.e. delete_service_mutation -pub struct DeleteServiceMutation; -type RawMutationResponse = delete_service_mutation::DeleteServiceMutationServiceRemoveImplementingServiceAndTriggerComposition; - -/// this struct contains all the info needed to print the result of the delete. -/// `updated_gateway` is true when composition succeeds and the gateway config -/// is updated for the gateway to consume. `composition_errors` is just a list -/// of strings for when there are composition errors as a result of the delete. -#[derive(Debug, PartialEq)] -pub struct DeleteServiceResponse { - pub updated_gateway: bool, - pub composition_errors: Option>, -} +/// Snake case of this name is the mod name. i.e. subgraph_delete_mutation +pub(crate) struct SubgraphDeleteMutation; /// The main function to be used from this module. This function fetches a /// schema from apollo studio and returns it in either sdl (default) or json format pub fn run( - variables: delete_service_mutation::Variables, + input: SubgraphDeleteInput, client: &StudioClient, -) -> Result { - let graph = variables.graph_id.clone(); - let response_data = client.post::(variables)?; +) -> Result { + let graph = input.graph_id.clone(); + let response_data = client.post::(input.into())?; let data = get_delete_data_from_response(response_data, graph)?; Ok(build_response(data)) } fn get_delete_data_from_response( - response_data: delete_service_mutation::ResponseData, + response_data: subgraph_delete_mutation::ResponseData, graph: String, -) -> Result { +) -> Result { let service_data = response_data .service .ok_or(RoverClientError::NoService { graph })?; @@ -50,7 +41,7 @@ fn get_delete_data_from_response( Ok(service_data.remove_implementing_service_and_trigger_composition) } -fn build_response(response: RawMutationResponse) -> DeleteServiceResponse { +fn build_response(response: MutationComposition) -> SubgraphDeleteResponse { let composition_errors: Vec = response .errors .iter() @@ -64,7 +55,7 @@ fn build_response(response: RawMutationResponse) -> DeleteServiceResponse { None }; - DeleteServiceResponse { + SubgraphDeleteResponse { updated_gateway: response.updated_gateway, composition_errors, } @@ -75,8 +66,6 @@ mod tests { use super::*; use serde_json::json; - type RawCompositionErrors = delete_service_mutation::DeleteServiceMutationServiceRemoveImplementingServiceAndTriggerCompositionErrors; - #[test] fn get_delete_data_from_response_works() { let json_response = json!({ @@ -91,19 +80,19 @@ mod tests { } } }); - let data: delete_service_mutation::ResponseData = + let data: subgraph_delete_mutation::ResponseData = serde_json::from_value(json_response).unwrap(); let output = get_delete_data_from_response(data, "mygraph".to_string()); assert!(output.is_ok()); - let expected_response = RawMutationResponse { + let expected_response = MutationComposition { errors: vec![ - Some(RawCompositionErrors { + Some(MutationCompositionErrors { message: "wow".to_string(), }), None, - Some(RawCompositionErrors { + Some(MutationCompositionErrors { message: "boo".to_string(), }), ], @@ -114,13 +103,13 @@ mod tests { #[test] fn build_response_works_with_successful_responses() { - let response = RawMutationResponse { + let response = MutationComposition { errors: vec![ - Some(RawCompositionErrors { + Some(MutationCompositionErrors { message: "wow".to_string(), }), None, - Some(RawCompositionErrors { + Some(MutationCompositionErrors { message: "boo".to_string(), }), ], @@ -130,7 +119,7 @@ mod tests { let parsed = build_response(response); assert_eq!( parsed, - DeleteServiceResponse { + SubgraphDeleteResponse { composition_errors: Some(vec!["wow".to_string(), "boo".to_string()]), updated_gateway: false, } @@ -139,7 +128,7 @@ mod tests { #[test] fn build_response_works_with_failure_responses() { - let response = RawMutationResponse { + let response = MutationComposition { errors: vec![], updated_gateway: true, }; @@ -147,7 +136,7 @@ mod tests { let parsed = build_response(response); assert_eq!( parsed, - DeleteServiceResponse { + SubgraphDeleteResponse { composition_errors: None, updated_gateway: true, } diff --git a/crates/rover-client/src/query/subgraph/delete/types.rs b/crates/rover-client/src/query/subgraph/delete/types.rs new file mode 100644 index 0000000000..82a82358f0 --- /dev/null +++ b/crates/rover-client/src/query/subgraph/delete/types.rs @@ -0,0 +1,36 @@ +use crate::query::subgraph::delete::mutation_runner::subgraph_delete_mutation; + +pub(crate) type MutationComposition = subgraph_delete_mutation::SubgraphDeleteMutationServiceRemoveImplementingServiceAndTriggerComposition; +pub(crate) type MutationVariables = subgraph_delete_mutation::Variables; + +#[cfg(test)] +pub(crate) type MutationCompositionErrors = subgraph_delete_mutation::SubgraphDeleteMutationServiceRemoveImplementingServiceAndTriggerCompositionErrors; + +#[derive(Debug, Clone, PartialEq)] +pub struct SubgraphDeleteInput { + pub graph_id: String, + pub variant: String, + pub subgraph: String, + pub dry_run: bool, +} + +/// this struct contains all the info needed to print the result of the delete. +/// `updated_gateway` is true when composition succeeds and the gateway config +/// is updated for the gateway to consume. `composition_errors` is just a list +/// of strings for when there are composition errors as a result of the delete. +#[derive(Debug, PartialEq)] +pub struct SubgraphDeleteResponse { + pub updated_gateway: bool, + pub composition_errors: Option>, +} + +impl From for MutationVariables { + fn from(input: SubgraphDeleteInput) -> Self { + Self { + graph_id: input.graph_id, + variant: input.variant, + subgraph: input.subgraph, + dry_run: input.dry_run, + } + } +} diff --git a/src/command/subgraph/delete.rs b/src/command/subgraph/delete.rs index f66a24485a..bcf7c61d4e 100644 --- a/src/command/subgraph/delete.rs +++ b/src/command/subgraph/delete.rs @@ -7,7 +7,7 @@ use crate::utils::client::StudioClientConfig; use crate::utils::parsers::{parse_graph_ref, GraphRef}; use crate::Result; -use rover_client::query::subgraph::delete::{self, DeleteServiceResponse}; +use rover_client::query::subgraph::delete::{self, SubgraphDeleteInput, SubgraphDeleteResponse}; #[derive(Debug, Serialize, StructOpt)] pub struct Delete { @@ -50,10 +50,10 @@ impl Delete { if !self.confirm { // run delete with dryRun, so we can preview composition errors let delete_dry_run_response = delete::run( - delete::delete_service_mutation::Variables { + SubgraphDeleteInput { graph_id: self.graph.name.clone(), - graph_variant: self.graph.variant.clone(), - name: self.subgraph.clone(), + variant: self.graph.variant.clone(), + subgraph: self.subgraph.clone(), dry_run: true, }, &client, @@ -69,10 +69,10 @@ impl Delete { } let delete_response = delete::run( - delete::delete_service_mutation::Variables { + SubgraphDeleteInput { graph_id: self.graph.name.clone(), - graph_variant: self.graph.variant.clone(), - name: self.subgraph.clone(), + variant: self.graph.variant.clone(), + subgraph: self.subgraph.clone(), dry_run: false, }, &client, @@ -83,7 +83,7 @@ impl Delete { } } -fn handle_dry_run_response(response: DeleteServiceResponse, subgraph: &str, graph_ref: &str) { +fn handle_dry_run_response(response: SubgraphDeleteResponse, subgraph: &str, graph_ref: &str) { let warn_prefix = Red.normal().paint("WARN:"); if let Some(errors) = response.composition_errors { eprintln!( @@ -111,7 +111,7 @@ fn confirm_delete() -> Result { } } -fn handle_response(response: DeleteServiceResponse, subgraph: &str, graph_ref: &str) { +fn handle_response(response: SubgraphDeleteResponse, subgraph: &str, graph_ref: &str) { let warn_prefix = Red.normal().paint("WARN:"); if response.updated_gateway { eprintln!( @@ -138,11 +138,11 @@ fn handle_response(response: DeleteServiceResponse, subgraph: &str, graph_ref: & #[cfg(test)] mod tests { - use super::{handle_response, DeleteServiceResponse}; + use super::{handle_response, SubgraphDeleteResponse}; #[test] fn handle_response_doesnt_error_with_all_successes() { - let response = DeleteServiceResponse { + let response = SubgraphDeleteResponse { composition_errors: None, updated_gateway: true, }; @@ -152,7 +152,7 @@ mod tests { #[test] fn handle_response_doesnt_error_with_all_failures() { - let response = DeleteServiceResponse { + let response = SubgraphDeleteResponse { composition_errors: Some(vec![ "a bad thing happened".to_string(), "another bad thing".to_string(),