Skip to content

Commit 235c602

Browse files
committed
error when a non-federated graph is about to be overwritten by a subgraph
1 parent c1d80dd commit 235c602

File tree

6 files changed

+94
-10
lines changed

6 files changed

+94
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
query IsFederatedGraph($graphId: ID!, $graphVariant: String!) {
2+
service(id: $graphId) {
3+
implementingServices(graphVariant: $graphVariant) {
4+
__typename
5+
}
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// PublishPartialSchemaMutation
2+
use crate::blocking::StudioClient;
3+
use crate::RoverClientError;
4+
use graphql_client::*;
5+
6+
#[derive(GraphQLQuery)]
7+
// The paths are relative to the directory where your `Cargo.toml` is located.
8+
// Both json and the GraphQL schema language are supported as sources for the schema
9+
#[graphql(
10+
query_path = "src/query/config/is_federated.graphql",
11+
schema_path = ".schema/schema.graphql",
12+
response_derives = "PartialEq, Debug, Serialize, Deserialize",
13+
deprecated = "warn"
14+
)]
15+
/// This struct is used to generate the module containing `Variables` and
16+
/// `ResponseData` structs.
17+
/// Snake case of this name is the mod name. i.e. publish_partial_schema_mutation
18+
pub struct IsFederatedGraph;
19+
20+
#[derive(Debug, PartialEq)]
21+
pub struct IsFederatedGraphResponse {
22+
pub result: bool,
23+
}
24+
25+
pub fn run(
26+
variables: is_federated_graph::Variables,
27+
client: &StudioClient,
28+
) -> Result<IsFederatedGraphResponse, RoverClientError> {
29+
let data = client.post::<IsFederatedGraph>(variables)?;
30+
let is_federated_response = data.service.unwrap();
31+
Ok(build_response(is_federated_response))
32+
}
33+
34+
type FederatedResponse = is_federated_graph::IsFederatedGraphService;
35+
type ImplementingServices = is_federated_graph::IsFederatedGraphServiceImplementingServices;
36+
37+
fn build_response(service: FederatedResponse) -> IsFederatedGraphResponse {
38+
match service.implementing_services {
39+
Some(typename) => match typename {
40+
ImplementingServices::FederatedImplementingServices => {
41+
IsFederatedGraphResponse { result: true }
42+
}
43+
ImplementingServices::NonFederatedImplementingService => {
44+
IsFederatedGraphResponse { result: false }
45+
}
46+
},
47+
None => IsFederatedGraphResponse { result: false },
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
/// runner for rover config whoami
22
pub mod whoami;
3+
4+
/// runner is_federated check
5+
pub mod is_federated;

installers/npm/package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

installers/npm/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@
3333
"console.table": "^0.10.0"
3434
},
3535
"devDependencies": {
36-
"prettier": "^2.2.1"
36+
"prettier": "^2.3.0"
3737
}
3838
}

src/command/subgraph/publish.rs

+33-8
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ use ansi_term::Colour::{Cyan, Red, Yellow};
22
use serde::Serialize;
33
use structopt::StructOpt;
44

5-
use crate::command::RoverStdout;
65
use crate::utils::{
76
client::StudioClientConfig,
87
git::GitContext,
98
loaders::load_schema_from_flag,
109
parsers::{parse_graph_ref, parse_schema_source, GraphRef, SchemaSource},
1110
};
12-
use crate::Result;
11+
use crate::{anyhow, Result};
12+
use crate::{command::RoverStdout, error::RoverError};
1313

14-
use rover_client::query::subgraph::publish::{self, PublishPartialSchemaResponse};
14+
use rover_client::query::{
15+
config::is_federated,
16+
subgraph::publish::{self, PublishPartialSchemaResponse},
17+
};
1518

1619
#[derive(Debug, Serialize, StructOpt)]
1720
pub struct Publish {
@@ -37,6 +40,10 @@ pub struct Publish {
3740
#[serde(skip_serializing)]
3841
subgraph: String,
3942

43+
/// Indicate whether to convert a non-federated graph into a subgraph
44+
#[structopt(short, long)]
45+
convert: bool,
46+
4047
/// Url of a running subgraph that a gateway can route operations to
4148
/// (often a deployed subgraph). May be left empty ("") or a placeholder url
4249
/// if not running a gateway in managed federation mode
@@ -64,6 +71,24 @@ impl Publish {
6471

6572
tracing::debug!("Schema Document to publish:\n{}", &schema_document);
6673

74+
// This response is used to check whether or not the current graph is federated.
75+
let federated_response = is_federated::run(
76+
is_federated::is_federated_graph::Variables {
77+
graph_id: self.graph.name.clone(),
78+
graph_variant: self.graph.variant.clone(),
79+
},
80+
&client,
81+
)?;
82+
83+
// We don't want to implicitly convert non-federated graph to subgraphs.
84+
// Error here if no --convert flag is passed _and_ the current context
85+
// is non-federated. Add a suggestion to require a --convert flag.
86+
if !federated_response.result && !self.convert {
87+
return Err(RoverError::new(anyhow!(
88+
"Could not publish a subgraph to a non-federated graph."
89+
)));
90+
}
91+
6792
let publish_response = publish::run(
6893
publish::publish_partial_schema_mutation::Variables {
6994
graph_id: self.graph.name.clone(),
@@ -81,12 +106,12 @@ impl Publish {
81106
&client,
82107
)?;
83108

84-
handle_response(publish_response, &self.subgraph, &self.graph.name);
109+
handle_publish_response(publish_response, &self.subgraph, &self.graph.name);
85110
Ok(RoverStdout::None)
86111
}
87112
}
88113

89-
fn handle_response(response: PublishPartialSchemaResponse, subgraph: &str, graph: &str) {
114+
fn handle_publish_response(response: PublishPartialSchemaResponse, subgraph: &str, graph: &str) {
90115
if response.service_was_created {
91116
eprintln!(
92117
"A new subgraph called '{}' for the '{}' graph was created",
@@ -120,7 +145,7 @@ fn handle_response(response: PublishPartialSchemaResponse, subgraph: &str, graph
120145

121146
#[cfg(test)]
122147
mod tests {
123-
use super::{handle_response, PublishPartialSchemaResponse};
148+
use super::{handle_publish_response, PublishPartialSchemaResponse};
124149

125150
// this test is a bit weird, since we can't test the output. We just verify it
126151
// doesn't error
@@ -133,7 +158,7 @@ mod tests {
133158
composition_errors: None,
134159
};
135160

136-
handle_response(response, "accounts", "my-graph");
161+
handle_publish_response(response, "accounts", "my-graph");
137162
}
138163

139164
#[test]
@@ -148,7 +173,7 @@ mod tests {
148173
]),
149174
};
150175

151-
handle_response(response, "accounts", "my-graph");
176+
handle_publish_response(response, "accounts", "my-graph");
152177
}
153178

154179
// TODO: test the actual output of the logs whenever we do design work

0 commit comments

Comments
 (0)