Skip to content

Commit a121cf4

Browse files
JakeDawkinstrevor-scheer
authored andcommitted
Delete federated service (#1192)
* Add service delete command and mutation * update checks operation to match new schema
1 parent 4f219c9 commit a121cf4

5 files changed

Lines changed: 252 additions & 3 deletions

File tree

packages/apollo-language-server/src/engine/index.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { REGISTER_OPERATIONS } from "./operations/registerOperations";
77
import { SCHEMA_TAGS_AND_FIELD_STATS } from "./operations/schemaTagsAndFieldStats";
88
import { UPLOAD_AND_COMPOSE_PARTIAL_SCHEMA } from "./operations/uploadAndComposePartialSchema";
99
import { CHECK_PARTIAL_SCHEMA } from "./operations/checkPartialSchema";
10+
import { REMOVE_SERVICE_AND_COMPOSE } from "./operations/removeServiceAndCompose";
1011
import {
1112
CheckSchema,
1213
CheckSchemaVariables,
@@ -22,7 +23,9 @@ import {
2223
SchemaTagInfo,
2324
SchemaTagInfoVariables,
2425
CheckPartialSchema,
25-
CheckPartialSchemaVariables
26+
CheckPartialSchemaVariables,
27+
RemoveServiceAndCompose,
28+
RemoveServiceAndComposeVariables
2629
} from "../graphqlTypes";
2730
import { SCHEMA_TAG_INFO_QUERY } from "./operations/schemaTagInfo";
2831

@@ -173,6 +176,25 @@ export class ApolloEngineClient extends GraphQLDataSource {
173176
});
174177
}
175178

179+
public async removeServiceAndCompose(
180+
variables: RemoveServiceAndComposeVariables
181+
) {
182+
return this.execute<RemoveServiceAndCompose>({
183+
query: REMOVE_SERVICE_AND_COMPOSE,
184+
variables
185+
}).then(({ data, errors }) => {
186+
if (errors) {
187+
throw new Error(errors.map(error => error.message).join("\n"));
188+
}
189+
190+
if (!data || !data.service) {
191+
throw new Error("Error in request from Engine");
192+
}
193+
194+
return data.service.removeImplementingServiceAndTriggerComposition;
195+
});
196+
}
197+
176198
public async validateOperations(variables: ValidateOperationsVariables) {
177199
return this.execute<ValidateOperations>({
178200
query: VALIDATE_OPERATIONS,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import gql from "graphql-tag";
2+
3+
export const REMOVE_SERVICE_AND_COMPOSE = gql`
4+
mutation RemoveServiceAndCompose(
5+
$id: ID!
6+
$graphVariant: String!
7+
$name: String!
8+
) {
9+
service(id: $id) {
10+
removeImplementingServiceAndTriggerComposition(
11+
graphVariant: $graphVariant
12+
name: $name
13+
) {
14+
compositionConfig {
15+
implementingServiceLocations {
16+
name
17+
path
18+
}
19+
}
20+
errors {
21+
locations {
22+
column
23+
line
24+
}
25+
message
26+
}
27+
warnings {
28+
locations {
29+
column
30+
line
31+
}
32+
message
33+
}
34+
updatedGateway
35+
}
36+
}
37+
}
38+
`;

packages/apollo-language-server/src/graphqlTypes.ts

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface CheckPartialSchema_service_validatePartialSchemaOfImplementingS
1111
/**
1212
* Hash of the composed schema
1313
*/
14-
schemaHash: string;
14+
schemaHash: string | null;
1515
}
1616

1717
export interface CheckPartialSchema_service_validatePartialSchemaOfImplementingServiceAgainstGraph_errors {
@@ -230,6 +230,102 @@ export interface RegisterOperationsVariables {
230230
/* eslint-disable */
231231
// This file was automatically generated and should not be edited.
232232

233+
// ====================================================
234+
// GraphQL mutation operation: RemoveServiceAndCompose
235+
// ====================================================
236+
237+
export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig_implementingServiceLocations {
238+
__typename: "ImplementingServiceLocation";
239+
/**
240+
* The name of the implementing service
241+
*/
242+
name: string;
243+
/**
244+
* The path in storage to access the implementing service config file
245+
*/
246+
path: string;
247+
}
248+
249+
export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig {
250+
__typename: "CompositionConfig";
251+
/**
252+
* List of implementing services that comprise a composed graph
253+
*/
254+
implementingServiceLocations: RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig_implementingServiceLocations[];
255+
}
256+
257+
export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors_locations {
258+
__typename: "SourceLocation";
259+
column: number;
260+
line: number;
261+
}
262+
263+
export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors {
264+
__typename: "SchemaCompositionError";
265+
locations: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors_locations | null)[];
266+
message: string;
267+
}
268+
269+
export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings_locations {
270+
__typename: "SourceLocation";
271+
column: number;
272+
line: number;
273+
}
274+
275+
export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings {
276+
__typename: "SchemaCompositionWarning";
277+
locations: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings_locations | null)[];
278+
message: string;
279+
}
280+
281+
export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition {
282+
__typename: "CompositionAndRemoveResult";
283+
/**
284+
* The produced composition config. Will be null if there are any errors
285+
*/
286+
compositionConfig: RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig | null;
287+
/**
288+
* List of errors during composition. Errors mean that Apollo was unable to compose the
289+
* graph's implementing services into a GraphQL schema. This partial schema should not be
290+
* published to the implementing service if there were any errors encountered
291+
*/
292+
errors: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors | null)[];
293+
/**
294+
* List of warnings encountered during composing implementing services into a complete schema.
295+
* Though a schema was composed for the graph with the proposed partial schema,
296+
* these warnings may indicate undesired behavior or lost information. We recommend that no service
297+
* is pushed with warnings that are not fully understood. Pushing an implementing service with warnings
298+
* in its composition result will result in updating the composition config.
299+
*/
300+
warnings: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings | null)[];
301+
/**
302+
* Whether the gateway link was updated.
303+
*/
304+
updatedGateway: boolean;
305+
}
306+
307+
export interface RemoveServiceAndCompose_service {
308+
__typename: "ServiceMutation";
309+
/**
310+
* Remove an implementing service from a graph and update its service list manifest
311+
*/
312+
removeImplementingServiceAndTriggerComposition: RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition;
313+
}
314+
315+
export interface RemoveServiceAndCompose {
316+
service: RemoveServiceAndCompose_service | null;
317+
}
318+
319+
export interface RemoveServiceAndComposeVariables {
320+
id: string;
321+
graphVariant: string;
322+
name: string;
323+
}
324+
325+
/* tslint:disable */
326+
/* eslint-disable */
327+
// This file was automatically generated and should not be edited.
328+
233329
// ====================================================
234330
// GraphQL query operation: SchemaTagInfo
235331
// ====================================================
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { flags } from "@oclif/command";
2+
3+
import { ProjectCommand } from "../../Command";
4+
5+
export default class ServiceDelete extends ProjectCommand {
6+
static description =
7+
"Delete a federated service from Engine and recompose remaining services";
8+
static flags = {
9+
...ProjectCommand.flags,
10+
tag: flags.string({
11+
char: "t",
12+
description: "The variant of the service to delete"
13+
}),
14+
federated: flags.boolean({
15+
char: "f",
16+
default: false,
17+
description:
18+
"Indicates that the schema is a partial schema from a federated service"
19+
}),
20+
serviceName: flags.string({
21+
required: true,
22+
description:
23+
"Provides the name of the implementing service for a federated graph"
24+
})
25+
};
26+
27+
async run() {
28+
let result;
29+
await this.runTasks(({ flags, project, config }) => [
30+
{
31+
title: "Removing service from Engine",
32+
task: async () => {
33+
if (!config.name) {
34+
throw new Error("No service found to link to Engine");
35+
}
36+
37+
if (!flags.federated) {
38+
this.error(
39+
"Deleting a service is only supported for federated services. Use the --federated flag if this is a federated service."
40+
);
41+
}
42+
43+
const graphVariant = flags.tag || config.tag || "current";
44+
45+
const {
46+
errors,
47+
warnings,
48+
updatedGateway
49+
} = await project.engine.removeServiceAndCompose({
50+
id: config.name,
51+
graphVariant,
52+
name: flags.serviceName
53+
});
54+
55+
result = {
56+
serviceName: flags.serviceName,
57+
graphVariant,
58+
graphName: config.name,
59+
warnings,
60+
errors,
61+
updatedGateway
62+
};
63+
64+
return;
65+
}
66+
}
67+
]);
68+
69+
this.log("\n");
70+
71+
if (result.errors && result.errors.length) {
72+
this.error(result.errors.map(error => error.message).join("\n"));
73+
}
74+
75+
if (result.warnings && result.warnings.length) {
76+
this.warn(result.warnings.map(warning => warning.message).join("\n"));
77+
}
78+
79+
if (result.updatedGateway) {
80+
this.log(
81+
`The ${result.serviceName} service with ${
82+
result.graphVariant
83+
} tag was removed from ${
84+
result.graphName
85+
}. Remaining services were composed.`
86+
);
87+
this.log("\n");
88+
}
89+
}
90+
}

packages/apollo/src/commands/service/push.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ export default class ServicePush extends ProjectCommand {
8686
graphVariant: config.tag,
8787
name: flags.serviceName || info.name,
8888
url: flags.serviceURL || info.url,
89-
revision: flags.serviceRevision || gitContext.commit,
89+
revision:
90+
flags.serviceRevision ||
91+
(gitContext && gitContext.commit) ||
92+
"",
9093
activePartialSchema: {
9194
sdl: info.sdl
9295
}

0 commit comments

Comments
 (0)