From 8f81911398ed20164a3d942aed9c368762b75e9c Mon Sep 17 00:00:00 2001 From: Praveen Gupta Date: Thu, 7 Sep 2023 17:38:31 +0200 Subject: [PATCH] Add AppSync graphqlschema and pipeline resolvers as hotswappable --- .../api/hotswap/appsync-mapping-templates.ts | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts b/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts index 2ed050c1ed406..189559cc15a5e 100644 --- a/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts +++ b/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts @@ -1,5 +1,7 @@ -import { ChangeHotswapResult, classifyChanges, HotswappableChangeCandidate, lowerCaseFirstCharacter, reportNonHotswappableChange, transformObjectKeys } from './common'; +import { GetSchemaCreationStatusRequest, GetSchemaCreationStatusResponse } from 'aws-sdk/clients/appsync'; +import { ChangeHotswapResult, classifyChanges, HotswappableChangeCandidate, lowerCaseFirstCharacter, transformObjectKeys } from './common'; import { ISDK } from '../aws-auth'; + import { EvaluateCloudFormationTemplate } from '../evaluate-cloudformation-template'; export async function isHotswappableAppSyncChange( @@ -7,23 +9,19 @@ export async function isHotswappableAppSyncChange( ): Promise { const isResolver = change.newValue.Type === 'AWS::AppSync::Resolver'; const isFunction = change.newValue.Type === 'AWS::AppSync::FunctionConfiguration'; + const isGraphQLSchema = change.newValue.Type === 'AWS::AppSync::GraphQLSchema'; - if (!isResolver && !isFunction) { + if (!isResolver && !isFunction && !isGraphQLSchema) { return []; } const ret: ChangeHotswapResult = []; - if (isResolver && change.newValue.Properties?.Kind === 'PIPELINE') { - reportNonHotswappableChange( - ret, - change, - undefined, - 'Pipeline resolvers cannot be hotswapped since they reference the FunctionId of the underlying functions, which cannot be resolved', - ); - return ret; - } - const classifiedChanges = classifyChanges(change, ['RequestMappingTemplate', 'ResponseMappingTemplate']); + const classifiedChanges = classifyChanges(change, [ + 'RequestMappingTemplate', + 'ResponseMappingTemplate', + 'Definition', + ]); classifiedChanges.reportNonHotswappablePropertyChanges(ret); const namesOfHotswappableChanges = Object.keys(classifiedChanges.hotswappableProps); @@ -49,6 +47,7 @@ export async function isHotswappableAppSyncChange( const sdkProperties: { [name: string]: any } = { ...change.oldValue.Properties, + Definition: change.newValue.Properties?.Definition, requestMappingTemplate: change.newValue.Properties?.RequestMappingTemplate, responseMappingTemplate: change.newValue.Properties?.ResponseMappingTemplate, }; @@ -57,13 +56,25 @@ export async function isHotswappableAppSyncChange( if (isResolver) { await sdk.appsync().updateResolver(sdkRequestObject).promise(); - } else { + } else if (isFunction) { const { functions } = await sdk.appsync().listFunctions({ apiId: sdkRequestObject.apiId }).promise(); const { functionId } = functions?.find(fn => fn.name === physicalName) ?? {}; await sdk.appsync().updateFunction({ ...sdkRequestObject, functionId: functionId!, }).promise(); + } else { + let schemaCreationResponse: GetSchemaCreationStatusResponse = await sdk.appsync().startSchemaCreation(sdkRequestObject).promise(); + while (schemaCreationResponse.status && ['PROCESSING', 'DELETING'].some(status => status === schemaCreationResponse.status)) { + await new Promise(resolve => setTimeout(resolve, 1000)); // poll every second + const getSchemaCreationStatusRequest: GetSchemaCreationStatusRequest = { + apiId: sdkRequestObject.apiId, + }; + schemaCreationResponse = await sdk.appsync().getSchemaCreationStatus(getSchemaCreationStatusRequest).promise(); + } + if (schemaCreationResponse.status === 'FAILED') { + throw new Error(schemaCreationResponse.details); + } } }, });