Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion packages/apollo-language-server/src/engine/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { REGISTER_OPERATIONS } from "./operations/registerOperations";
import { SCHEMA_TAGS_AND_FIELD_STATS } from "./operations/schemaTagsAndFieldStats";
import { UPLOAD_AND_COMPOSE_PARTIAL_SCHEMA } from "./operations/uploadAndComposePartialSchema";
import { CHECK_PARTIAL_SCHEMA } from "./operations/checkPartialSchema";
import { REMOVE_SERVICE_AND_COMPOSE } from "./operations/removeServiceAndCompose";
import {
CheckSchema,
CheckSchemaVariables,
Expand All @@ -22,7 +23,9 @@ import {
SchemaTagInfo,
SchemaTagInfoVariables,
CheckPartialSchema,
CheckPartialSchemaVariables
CheckPartialSchemaVariables,
RemoveServiceAndCompose,
RemoveServiceAndComposeVariables
} from "../graphqlTypes";
import { SCHEMA_TAG_INFO_QUERY } from "./operations/schemaTagInfo";

Expand Down Expand Up @@ -173,6 +176,25 @@ export class ApolloEngineClient extends GraphQLDataSource {
});
}

public async removeServiceAndCompose(
variables: RemoveServiceAndComposeVariables
) {
return this.execute<RemoveServiceAndCompose>({
query: REMOVE_SERVICE_AND_COMPOSE,
variables
}).then(({ data, errors }) => {
if (errors) {
throw new Error(errors.map(error => error.message).join("\n"));
}

if (!data || !data.service) {
throw new Error("Error in request from Engine");
}

return data.service.removeImplementingServiceAndTriggerComposition;
});
}

public async validateOperations(variables: ValidateOperationsVariables) {
return this.execute<ValidateOperations>({
query: VALIDATE_OPERATIONS,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import gql from "graphql-tag";

export const REMOVE_SERVICE_AND_COMPOSE = gql`
mutation RemoveServiceAndCompose(
$id: ID!
$graphVariant: String!
$name: String!
) {
service(id: $id) {
removeImplementingServiceAndTriggerComposition(
graphVariant: $graphVariant
name: $name
) {
compositionConfig {
implementingServiceLocations {
name
path
}
}
errors {
locations {
column
line
}
message
}
warnings {
locations {
column
line
}
message
}
updatedGateway
}
}
}
`;
98 changes: 97 additions & 1 deletion packages/apollo-language-server/src/graphqlTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface CheckPartialSchema_service_validatePartialSchemaOfImplementingS
/**
* Hash of the composed schema
*/
schemaHash: string;
schemaHash: string | null;
}

export interface CheckPartialSchema_service_validatePartialSchemaOfImplementingServiceAgainstGraph_errors {
Expand Down Expand Up @@ -216,6 +216,102 @@ export interface RegisterOperationsVariables {
/* eslint-disable */
// This file was automatically generated and should not be edited.

// ====================================================
// GraphQL mutation operation: RemoveServiceAndCompose
// ====================================================

export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig_implementingServiceLocations {
__typename: "ImplementingServiceLocation";
/**
* The name of the implementing service
*/
name: string;
/**
* The path in storage to access the implementing service config file
*/
path: string;
}

export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig {
__typename: "CompositionConfig";
/**
* List of implementing services that comprise a composed graph
*/
implementingServiceLocations: RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig_implementingServiceLocations[];
}

export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors_locations {
__typename: "SourceLocation";
column: number;
line: number;
}

export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors {
__typename: "SchemaCompositionError";
locations: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors_locations | null)[];
message: string;
}

export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings_locations {
__typename: "SourceLocation";
column: number;
line: number;
}

export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings {
__typename: "SchemaCompositionWarning";
locations: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings_locations | null)[];
message: string;
}

export interface RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition {
__typename: "CompositionAndRemoveResult";
/**
* The produced composition config. Will be null if there are any errors
*/
compositionConfig: RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_compositionConfig | null;
/**
* List of errors during composition. Errors mean that Apollo was unable to compose the
* graph's implementing services into a GraphQL schema. This partial schema should not be
* published to the implementing service if there were any errors encountered
*/
errors: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_errors | null)[];
/**
* List of warnings encountered during composing implementing services into a complete schema.
* Though a schema was composed for the graph with the proposed partial schema,
* these warnings may indicate undesired behavior or lost information. We recommend that no service
* is pushed with warnings that are not fully understood. Pushing an implementing service with warnings
* in its composition result will result in updating the composition config.
*/
warnings: (RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition_warnings | null)[];
/**
* Whether the gateway link was updated.
*/
updatedGateway: boolean;
}

export interface RemoveServiceAndCompose_service {
__typename: "ServiceMutation";
/**
* Remove an implementing service from a graph and update its service list manifest
*/
removeImplementingServiceAndTriggerComposition: RemoveServiceAndCompose_service_removeImplementingServiceAndTriggerComposition;
}

export interface RemoveServiceAndCompose {
service: RemoveServiceAndCompose_service | null;
}

export interface RemoveServiceAndComposeVariables {
id: string;
graphVariant: string;
name: string;
}

/* tslint:disable */
/* eslint-disable */
// This file was automatically generated and should not be edited.

// ====================================================
// GraphQL query operation: SchemaTagInfo
// ====================================================
Expand Down
2 changes: 1 addition & 1 deletion packages/apollo/src/commands/service/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ interface TasksOutput {
federation?: {
errors: ({ message: string } | null)[];
warnings: ({ message: string } | null)[];
schemaHash?: string;
schemaHash?: string | null;
};
}

Expand Down
90 changes: 90 additions & 0 deletions packages/apollo/src/commands/service/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { flags } from "@oclif/command";

import { ProjectCommand } from "../../Command";

export default class ServiceDelete extends ProjectCommand {
static description =
"Delete a federated service from Engine and recompose remaining services";
static flags = {
...ProjectCommand.flags,
tag: flags.string({
char: "t",
description: "The variant of the service to delete"
}),
federated: flags.boolean({
char: "f",
default: false,
description:
"Indicates that the schema is a partial schema from a federated service"
}),
serviceName: flags.string({
required: true,
description:
"Provides the name of the implementing service for a federated graph"
})
};

async run() {
let result;
await this.runTasks(({ flags, project, config }) => [
{
title: "Removing service from Engine",
task: async () => {
if (!config.name) {
throw new Error("No service found to link to Engine");
}

if (!flags.federated) {
this.error(
"Deleting a service is only supported for federated services. Use the --federated flag if this is a federated service."
);
}

const graphVariant = flags.tag || config.tag || "current";

const {
errors,
warnings,
updatedGateway
} = await project.engine.removeServiceAndCompose({
id: config.name,
graphVariant,
name: flags.serviceName
});

result = {
serviceName: flags.serviceName,
graphVariant,
graphName: config.name,
warnings,
errors,
updatedGateway
};

return;
}
}
]);

this.log("\n");

if (result.errors && result.errors.length) {
this.error(result.errors.map(error => error.message).join("\n"));
}

if (result.warnings && result.warnings.length) {
this.warn(result.warnings.map(warning => warning.message).join("\n"));
}

if (result.updatedGateway) {
this.log(
`The ${result.serviceName} service with ${
result.graphVariant
} tag was removed from ${
result.graphName
}. Remaining services were composed.`
);
this.log("\n");
}
}
}
5 changes: 4 additions & 1 deletion packages/apollo/src/commands/service/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ export default class ServicePush extends ProjectCommand {
graphVariant: config.tag,
name: flags.serviceName || info.name,
url: flags.serviceURL || info.url,
revision: flags.serviceRevision || gitContext.commit,
revision:
flags.serviceRevision ||
(gitContext && gitContext.commit) ||
"",
activePartialSchema: {
sdl: info.sdl
}
Expand Down