Skip to content

Commit

Permalink
chore: refactor subgraph delete (#639)
Browse files Browse the repository at this point in the history
  • Loading branch information
EverlastingBugstopper authored Jun 28, 2021
1 parent 9b86870 commit cfadb04
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 53 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions crates/rover-client/src/query/subgraph/delete/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mod mutation_runner;

pub(crate) mod types;

pub use mutation_runner::run;
pub use types::{SubgraphDeleteInput, SubgraphDeleteResponse};
Original file line number Diff line number Diff line change
@@ -1,56 +1,47 @@
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<Vec<String>>,
}
/// 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<DeleteServiceResponse, RoverClientError> {
let graph = variables.graph_id.clone();
let response_data = client.post::<DeleteServiceMutation>(variables)?;
) -> Result<SubgraphDeleteResponse, RoverClientError> {
let graph = input.graph_id.clone();
let response_data = client.post::<SubgraphDeleteMutation>(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<RawMutationResponse, RoverClientError> {
) -> Result<MutationComposition, RoverClientError> {
let service_data = response_data
.service
.ok_or(RoverClientError::NoService { graph })?;

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<String> = response
.errors
.iter()
Expand All @@ -64,7 +55,7 @@ fn build_response(response: RawMutationResponse) -> DeleteServiceResponse {
None
};

DeleteServiceResponse {
SubgraphDeleteResponse {
updated_gateway: response.updated_gateway,
composition_errors,
}
Expand All @@ -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!({
Expand All @@ -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(),
}),
],
Expand All @@ -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(),
}),
],
Expand All @@ -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,
}
Expand All @@ -139,15 +128,15 @@ mod tests {

#[test]
fn build_response_works_with_failure_responses() {
let response = RawMutationResponse {
let response = MutationComposition {
errors: vec![],
updated_gateway: true,
};

let parsed = build_response(response);
assert_eq!(
parsed,
DeleteServiceResponse {
SubgraphDeleteResponse {
composition_errors: None,
updated_gateway: true,
}
Expand Down
36 changes: 36 additions & 0 deletions crates/rover-client/src/query/subgraph/delete/types.rs
Original file line number Diff line number Diff line change
@@ -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<Vec<String>>,
}

impl From<SubgraphDeleteInput> for MutationVariables {
fn from(input: SubgraphDeleteInput) -> Self {
Self {
graph_id: input.graph_id,
variant: input.variant,
subgraph: input.subgraph,
dry_run: input.dry_run,
}
}
}
24 changes: 12 additions & 12 deletions src/command/subgraph/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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!(
Expand Down Expand Up @@ -111,7 +111,7 @@ fn confirm_delete() -> Result<bool> {
}
}

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!(
Expand All @@ -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,
};
Expand All @@ -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(),
Expand Down

0 comments on commit cfadb04

Please sign in to comment.