Skip to content

Commit

Permalink
feat: add logRetention option for mergeSchema lambdas with default to…
Browse files Browse the repository at this point in the history
… NEVER
  • Loading branch information
arnaud-deprez committed Jul 10, 2024
1 parent c491e67 commit cc3f26a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/source-api-association-merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CfnResource, CustomResource, Duration, Stack } from 'aws-cdk-lib';
import { ISourceApiAssociation } from 'aws-cdk-lib/aws-appsync';
import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Code, Runtime, SingletonFunction } from 'aws-cdk-lib/aws-lambda';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
import { Provider } from 'aws-cdk-lib/custom-resources';
import { Construct, IConstruct } from 'constructs';

Expand Down Expand Up @@ -43,6 +44,13 @@ export interface SourceApiAssociationMergeOperationProviderProps {
* @default Duration.minutes(15)
*/
readonly totalTimeout?: Duration;

/**
* The number of days log events are kept in CloudWatch Logs for the schemaMergeLambda and sourceApiStablizationLambda.
*
* @default RetentionDays.INFINITE
*/
readonly logRetention?: RetentionDays;
}

/**
Expand Down Expand Up @@ -75,6 +83,7 @@ export class SourceApiAssociationMergeOperationProvider extends Construct implem
handler: 'index.onEvent',
timeout: Duration.minutes(2),
uuid: '6148f39b-95bb-47e7-8a35-40adb8b93a7b',
logRetention: props.logRetention,
});

this.sourceApiStablizationLambda = new SingletonFunction(this, 'PollSourceApiMergeLambda', {
Expand All @@ -83,13 +92,15 @@ export class SourceApiAssociationMergeOperationProvider extends Construct implem
handler: 'index.isComplete',
timeout: Duration.minutes(2),
uuid: '163e01ec-6f29-4bf4-b3b1-11245b00a6bc',
logRetention: props.logRetention,
});

const provider = new Provider(this, 'SchemaMergeOperationProvider', {
onEventHandler: this.schemaMergeLambda,
isCompleteHandler: this.sourceApiStablizationLambda,
queryInterval: props.pollingInterval ?? Duration.seconds(5),
totalTimeout: props.totalTimeout ?? Duration.minutes(15),
logRetention: props.logRetention,
});

this.serviceToken = provider.serviceToken;
Expand Down Expand Up @@ -127,6 +138,13 @@ export interface SourceApiAssociationMergeOperationProps {
*/
readonly mergeOperationProvider?: ISourceApiAssociationMergeOperationProvider;

/**
* The default merge operation provider props to use when it is charge of creating a new merge operation provider.
*
* @default { pollingInterval: Duration.seconds(30) }
*/
readonly defaultMergeOperationProviderProps?: SourceApiAssociationMergeOperationProviderProps;

/**
* The version identifier for the schema merge operation. Any change to the version identifier will trigger a merge on the next
* update. Use the version identifier property to control when the source API metadata is merged.
Expand Down Expand Up @@ -192,7 +210,7 @@ export class SourceApiAssociationMergeOperation extends Construct {

var mergeOperationProvider = props.mergeOperationProvider;
if (!mergeOperationProvider) {
mergeOperationProvider = this.getOrCreateMergeOperationProvider();
mergeOperationProvider = this.getOrCreateMergeOperationProvider(props.defaultMergeOperationProviderProps ?? {});
}

mergeOperationProvider.associateSourceApiAssociation(props.sourceApiAssociation);
Expand Down Expand Up @@ -241,13 +259,14 @@ export class SourceApiAssociationMergeOperation extends Construct {
* Get an existing merge operation provider from the current stack or create a new stack scoped merge operation provider.
* @returns SourceApiAssociationMergeOperationProvider
*/
private getOrCreateMergeOperationProvider(): SourceApiAssociationMergeOperationProvider {
private getOrCreateMergeOperationProvider(props: SourceApiAssociationMergeOperationProviderProps): SourceApiAssociationMergeOperationProvider {
const constructName = 'SchemaMergeOperationProvider';
const stack = Stack.of(this);
const existing = stack.node.tryFindChild(constructName);
if (!existing) {
return new SourceApiAssociationMergeOperationProvider(stack, 'SchemaMergeOperationProvider', {
pollingInterval: Duration.seconds(30),
...props,
});
} else {
return existing as SourceApiAssociationMergeOperationProvider;
Expand Down
17 changes: 17 additions & 0 deletions test/source-api-association-merge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import { Template } from 'aws-cdk-lib/assertions';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as logs from 'aws-cdk-lib/aws-logs';
import * as cdk from 'aws-cdk-lib/core';
import { SourceApiAssociationMergeOperation } from '../src';

Expand Down Expand Up @@ -112,6 +113,22 @@ test('source api association merge operation with always update', () => {

Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 5);
Template.fromStack(stack).resourceCountIs('Custom::AppSyncSourceApiMergeOperation', 1);
Template.fromStack(stack).resourceCountIs('Custom::LogRetention', 0);
});

test('source api association merge operation with logRetention and pollingInterval set', () => {
new SourceApiAssociationMergeOperation(stack, 'SourceApi1Merge', {
sourceApiAssociation: sourceApiAssociation1,
alwaysMergeOnStackUpdate: true,
defaultMergeOperationProviderProps: {
logRetention: logs.RetentionDays.ONE_DAY,
pollingInterval: cdk.Duration.minutes(1),
},
});

Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 6); // +1 for log retention cleanup
Template.fromStack(stack).resourceCountIs('Custom::AppSyncSourceApiMergeOperation', 1);
Template.fromStack(stack).resourceCountIs('Custom::LogRetention', 2);
});

test('source api association merge operations with version identifier', () => {
Expand Down

0 comments on commit cc3f26a

Please sign in to comment.