Skip to content

Commit

Permalink
feat: get datasource map for migration (#2668)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpilch committed Sep 24, 2024
1 parent 0a68a53 commit f20ba2a
Show file tree
Hide file tree
Showing 14 changed files with 1,668 additions and 2,830 deletions.
6 changes: 3 additions & 3 deletions dependency_licenses.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ const generateTransformParameters = (
allowDestructiveGraphqlSchemaUpdates: false,
replaceTableUponGsiUpdate: false,
allowGen1Patterns: true,
// TODO: decide name before merging to main
enableGen2Migration: featureFlagProvider.getBoolean('enableGen2Migration'),
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '@aws-amplify/graphql-transformer-core';
import { InputObjectTypeDefinitionNode, InputValueDefinitionNode, NamedTypeNode, parse } from 'graphql';
import { getBaseType } from 'graphql-transformer-common';
import { Template } from 'aws-cdk-lib/assertions';
import { Template, Match } from 'aws-cdk-lib/assertions';
import { testTransform } from '@aws-amplify/graphql-transformer-test-utils';
import { PrimaryKeyTransformer } from '@aws-amplify/graphql-index-transformer';
import { VpcConfig, ModelDataSourceStrategySqlDbType, SQLLambdaModelDataSourceStrategy } from '@aws-amplify/graphql-transformer-interfaces';
Expand Down Expand Up @@ -2316,4 +2316,99 @@ describe('ModelTransformer:', () => {
expect(directiveNames).toContain('aws_iam');
});
});

describe('migration', () => {
it('should output data source mapping', async () => {
const validSchema = `
type Post @model {
id: ID!
title: String!
}
`;

const out = testTransform({
schema: validSchema,
transformers: [new ModelTransformer()],
transformParameters: {
enableGen2Migration: true,
},
});
expect(out).toBeDefined();
const template = Template.fromJSON(out.rootStack);
template.hasOutput('DataSourceMappingOutput', {
Value: Match.objectLike({
'Fn::Join': [
'',
[
'{"Post":"',
{
'Fn::GetAtt': ['Post', 'Outputs.transformerrootstackPostPostTable34CAE87BRef'],
},
'"}',
],
],
}),
Description: 'Mapping of model name to data source table name.',
});
});

it('should set table removal policy to retain', () => {
const validSchema = `
type Post @model {
id: ID!
title: String!
}
`;

const out = testTransform({
schema: validSchema,
transformers: [new ModelTransformer()],
transformParameters: {
enableGen2Migration: true,
},
});
expect(out).toBeDefined();
const postStack = out.stacks['Post'];
const template = Template.fromJSON(postStack);
template.hasResource('AWS::DynamoDB::Table', {
DeletionPolicy: 'Retain',
Properties: {
TableName: {
'Fn::Join': [
'',
[
'Post-',
{
Ref: 'referencetotransformerrootstackGraphQLAPI20497F53ApiId',
},
'-',
{
Ref: 'referencetotransformerrootstackenv10C5A902Ref',
},
],
],
},
},
});
});

describe('does not add SQL data sources to mapping', () => {
test.each(sqlDatasources)('%s', (dbType) => {
const validSchema = `
type Post @model {
id: ID! @primaryKey
title: String!
}
`;

const out = testTransform({
schema: validSchema,
transformers: [new ModelTransformer(), new PrimaryKeyTransformer()],
dataSourceStrategies: constructDataSourceStrategies(validSchema, makeStrategy(dbType)),
});
expect(out).toBeDefined();
expect(out.rootStack.Outputs?.DataSourceMappingOutput).toBeUndefined();
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
TransformerTransformSchemaStepContextProvider,
TransformerValidationStepContextProvider,
DataSourceStrategiesProvider,
DataSourceProvider,
} from '@aws-amplify/graphql-transformer-interfaces';
import { ModelDirective } from '@aws-amplify/graphql-directives';
import { ITable } from 'aws-cdk-lib/aws-dynamodb';
Expand Down Expand Up @@ -323,9 +324,31 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
};

generateResolvers = (context: TransformerContextProvider): void => {
const dataSourceMapping: Record<string, string> = {};
this.resourceGeneratorMap.forEach((generator) => {
generator.generateResources(context);
const ddbDatasources = Object.entries(generator.getDatasourceMap()).filter(
([, datasource]) => datasource.ds.type === 'AMAZON_DYNAMODB',
);
ddbDatasources.forEach(([modelName, datasource]) => {
if (datasource.ds.dynamoDbConfig && !cdk.isResolvableObject(datasource.ds.dynamoDbConfig)) {
dataSourceMapping[modelName] = datasource.ds.dynamoDbConfig.tableName;
}
// TODO: probably need a link to docs for this
console.warn(
`Could not resolve table name for ${modelName}. DataSourceMappingOutput is incomplete. Please manually add ${modelName} to the mapping for your migration.`,
);
});
});
if (context.transformParameters.enableGen2Migration && context.transformParameters.enableTransformerCfnOutputs) {
const { scope } = context.stackManager;
// TODO: decide final naming before merge to main
new cdk.CfnOutput(cdk.Stack.of(scope), 'DataSourceMappingOutput', {
value: cdk.Stack.of(scope).toJsonString(dataSourceMapping),
description: 'Mapping of model name to data source table name.',
exportName: cdk.Fn.join(':', [cdk.Aws.STACK_NAME, 'DataSourceMappingOutput']),
});
}
};

generateGetResolver = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ export class DynamoModelResourceGenerator extends ModelResourceGenerator {
expression: cdk.Fn.conditionEquals(pointInTimeRecovery, 'true'),
});

const removalPolicy = this.options.EnableDeletionProtection ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY;
const removalPolicy =
this.options.EnableDeletionProtection || context.transformParameters.enableGen2Migration
? cdk.RemovalPolicy.RETAIN
: cdk.RemovalPolicy.DESTROY;

// Expose a way in context to allow proper resource naming
const table = new Table(scope, tableLogicalName, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,4 +730,8 @@ export abstract class ModelResourceGenerator {

return fields;
};

getDatasourceMap(): Record<string, DataSourceProvider> {
return this.datasourceMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ export const defaultTransformParameters: TransformParameters = {

// Search Params
enableSearchNodeToNodeEncryption: false,

// Migration
enableGen2Migration: false,
};
1 change: 1 addition & 0 deletions packages/amplify-graphql-transformer-interfaces/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@ export type TransformParameters = {
enableAutoIndexQueryNames: boolean;
respectPrimaryKeyAttributesOnConnectionField: boolean;
enableSearchNodeToNodeEncryption: boolean;
enableGen2Migration: boolean;
};

// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@ export type TransformParameters = {

// Search Params
enableSearchNodeToNodeEncryption: boolean;

// Migration
enableGen2Migration: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const defaultTransformConfig: TransformConfig = {
allowDestructiveGraphqlSchemaUpdates: false,
replaceTableUponGsiUpdate: false,
allowGen1Patterns: true,
enableGen2Migration: false,
},
};

Expand Down
1 change: 1 addition & 0 deletions packages/amplify-util-mock/src/__e2e__/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const defaultTransformParams: Pick<ExecuteTransformConfig, 'transformersF
allowDestructiveGraphqlSchemaUpdates: false,
replaceTableUponGsiUpdate: false,
allowGen1Patterns: true,
enableGen2Migration: false,
},
};

Expand Down
1 change: 1 addition & 0 deletions packages/graphql-transformer-common/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ export class ResourceConstants {
AuthCognitoUserPoolIdOutput: string;
AuthCognitoUserPoolNativeClientOutput: string;
AuthCognitoUserPoolJSClientOutput: string;
DataSourceMappingOutput: string;
};
// (undocumented)
static PARAMETERS: {
Expand Down
3 changes: 3 additions & 0 deletions packages/graphql-transformer-common/src/ResourceConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ export class ResourceConstants {
AuthCognitoUserPoolIdOutput: 'AuthCognitoUserPoolIdOutput',
AuthCognitoUserPoolNativeClientOutput: 'AuthCognitoUserPoolNativeClientId',
AuthCognitoUserPoolJSClientOutput: 'AuthCognitoUserPoolJSClientId',

// Migration
DataSourceMappingOutput: 'DataSourceMappingOutput',
};

public static METADATA = {};
Expand Down
Loading

0 comments on commit f20ba2a

Please sign in to comment.