Skip to content

Commit

Permalink
Add AppSync graphqlschema and pipeline resolvers as hotswappable
Browse files Browse the repository at this point in the history
  • Loading branch information
Amplifiyer committed Sep 7, 2023
1 parent b04f4c4 commit 8f81911
Showing 1 changed file with 24 additions and 13 deletions.
37 changes: 24 additions & 13 deletions packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
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(
logicalId: string, change: HotswappableChangeCandidate, evaluateCfnTemplate: EvaluateCloudFormationTemplate,
): Promise<ChangeHotswapResult> {
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);
Expand All @@ -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,
};
Expand All @@ -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);
}
}
},
});
Expand Down

0 comments on commit 8f81911

Please sign in to comment.