Skip to content
Draft
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
5 changes: 5 additions & 0 deletions .changeset/tasty-wings-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@aws-amplify/backend-data': minor
---

Enabled a new "adoption" strategy for moving DynamoDB tables from Gen1 to Gen2, which will require an import operation. The migrated table will be fully managed by the Gen2 stack.
103 changes: 66 additions & 37 deletions packages/backend-data/src/convert_schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ void describe('convertSchemaToCDK', () => {
echo(message: String!): String!
}
`;
const convertedDefinition = convertSchemaToCDK(
graphqlSchema,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: graphqlSchema,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});
assert.deepEqual(convertedDefinition.schema, graphqlSchema);
assert.deepEqual(convertedDefinition.dataSourceStrategies, {
Todo: {
Expand All @@ -107,11 +107,11 @@ void describe('convertSchemaToCDK', () => {
}),
})
.authorization((allow) => allow.publicApiKey());
const convertedDefinition = convertSchemaToCDK(
typedSchema,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: typedSchema,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});
assert.deepEqual(
removeWhiteSpaceForComparison(convertedDefinition.schema),
removeWhiteSpaceForComparison(expectedGraphqlSchema),
Expand All @@ -135,11 +135,11 @@ void describe('convertSchemaToCDK', () => {
}),
})
.authorization((allow) => allow.publicApiKey());
const convertedDefinition = convertSchemaToCDK(
typedSchema,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: typedSchema,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});
assert.deepEqual(convertedDefinition.dataSourceStrategies, {
Todo: {
dbType: 'DYNAMODB',
Expand All @@ -152,12 +152,12 @@ void describe('convertSchemaToCDK', () => {
});
});

void it('uses the only appropriate dbType and provisioningStrategy', () => {
const convertedDefinition = convertSchemaToCDK(
'type Todo @model @auth(rules: { allow: public }) { id: ID! }',
secretResolver,
void it('uses the default dbType and provisioningStrategy', () => {
const convertedDefinition = convertSchemaToCDK({
schema: 'type Todo @model @auth(rules: { allow: public }) { id: ID! }',
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});
assert.equal(
Object.values(convertedDefinition.dataSourceStrategies).length,
1,
Expand Down Expand Up @@ -198,11 +198,11 @@ void describe('convertSchemaToCDK', () => {
.authorization((allow) => allow.publicApiKey()),
});

const convertedDefinition = convertSchemaToCDK(
modified,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: modified,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});

assert.equal(
Object.values(convertedDefinition.dataSourceStrategies).length,
Expand Down Expand Up @@ -253,11 +253,11 @@ void describe('convertSchemaToCDK', () => {
.authorization((allow) => allow.publicApiKey()),
});

const convertedDefinition = convertSchemaToCDK(
modified,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: modified,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});

assert.equal(
Object.values(convertedDefinition.dataSourceStrategies).length,
Expand Down Expand Up @@ -337,11 +337,11 @@ void describe('convertSchemaToCDK', () => {
.authorization((allow) => allow.publicApiKey()),
});

const convertedDefinition = convertSchemaToCDK(
modified,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: modified,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});

assert.equal(
Object.values(convertedDefinition.dataSourceStrategies).length,
Expand Down Expand Up @@ -420,11 +420,11 @@ void describe('convertSchemaToCDK', () => {
.authorization((allow) => allow.publicApiKey()),
});

const convertedDefinition = convertSchemaToCDK(
modified,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: modified,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});

assert.equal(
Object.values(convertedDefinition.dataSourceStrategies).length,
Expand Down Expand Up @@ -480,11 +480,11 @@ void describe('convertSchemaToCDK', () => {
.authorization((allow) => allow.publicApiKey()),
});

const convertedDefinition = convertSchemaToCDK(
modified,
secretResolver,
const convertedDefinition = convertSchemaToCDK({
schema: modified,
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
);
});

assert.equal(
Object.values(convertedDefinition.dataSourceStrategies).length,
Expand Down Expand Up @@ -514,4 +514,33 @@ void describe('convertSchemaToCDK', () => {
},
);
});

void it('produces IMPORTED strategy for importedTableName', () => {
const result = convertSchemaToCDK({
schema: 'type Todo @model { id: ID! }',
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
importedTableName: 'ExistingTable',
});
assert.deepEqual(Object.values(result.dataSourceStrategies)[0], {
dbType: 'DYNAMODB',
provisionStrategy: 'IMPORTED_AMPLIFY_TABLE',
tableName: 'ExistingTable',
});
});

void it('produces ADOPTED strategy for shouldAdoptExistingTable', () => {
const result = convertSchemaToCDK({
schema: 'type Todo @model { id: ID! }',
backendSecretResolver: secretResolver,
stableBackendIdentifiers,
importedTableName: 'AdoptedTable',
shouldAdoptExistingTable: true,
});
assert.deepEqual(Object.values(result.dataSourceStrategies)[0], {
dbType: 'DYNAMODB',
provisionStrategy: 'ADOPTED_AMPLIFY_TABLE',
tableName: 'AdoptedTable',
});
});
});
42 changes: 32 additions & 10 deletions packages/backend-data/src/convert_schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ const IMPORTED_DYNAMO_DATA_SOURCE_STRATEGY = {
provisionStrategy: 'IMPORTED_AMPLIFY_TABLE',
} as const;

// Adopted strategy where Amplify will synthesize a managed CFN table resource
const ADOPTED_DYNAMO_DATA_SOURCE_STRATEGY = {
dbType: 'DYNAMODB',
provisionStrategy: 'ADOPTED_AMPLIFY_TABLE',
} as const;

Comment on lines +75 to +80
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the important part.

// Translate the external engine types to the config values
// Reference: https://github.com/aws-amplify/amplify-category-api/blob/fd7f6fbc17c199331c4b04debaff69ea0424cd74/packages/amplify-graphql-api-construct/src/model-datasource-strategy-types.ts#L25
const SQL_DB_TYPES = {
Expand All @@ -81,18 +87,28 @@ const SQL_DB_TYPES = {

/**
* Given an input schema type, produce the relevant CDK Graphql Def interface
* @param schema TS schema builder definition or string GraphQL schema
* @param backendSecretResolver secret resolver
* @param stableBackendIdentifiers backend identifiers
* @param importedTableName table name to use for imported models. If not defined the model is not imported.
* @param params configuration parameters
* @param params.schema TS schema builder definition or string GraphQL schema
* @param params.backendSecretResolver secret resolver
* @param params.stableBackendIdentifiers backend identifiers
* @param params.importedTableName table name to use for imported models. If not defined the model is not imported.
* @param params.shouldAdoptExistingTable whether to adopt the existing table
* @returns the cdk graphql definition interface
*/
export const convertSchemaToCDK = (
schema: DataSchema,
backendSecretResolver: BackendSecretResolver,
stableBackendIdentifiers: StableBackendIdentifiers,
importedTableName?: string,
): IAmplifyDataDefinition => {
export const convertSchemaToCDK = (params: {
schema: DataSchema;
backendSecretResolver: BackendSecretResolver;
stableBackendIdentifiers: StableBackendIdentifiers;
importedTableName?: string;
shouldAdoptExistingTable?: boolean;
}): IAmplifyDataDefinition => {
const {
schema,
backendSecretResolver,
stableBackendIdentifiers,
importedTableName,
shouldAdoptExistingTable,
} = params;
if (isDataSchema(schema)) {
/**
* This is not super obvious, but the IAmplifyDataDefinition interface requires a record of each model type to a
Expand Down Expand Up @@ -146,6 +162,12 @@ export const convertSchemaToCDK = (
}

if (importedTableName) {
if (shouldAdoptExistingTable) {
return AmplifyDataDefinition.fromString(schema, {
...ADOPTED_DYNAMO_DATA_SOURCE_STRATEGY,
tableName: importedTableName,
} as unknown as ModelDataSourceStrategy);
}
Comment on lines +165 to +170
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the important part.

return AmplifyDataDefinition.fromString(schema, {
...IMPORTED_DYNAMO_DATA_SOURCE_STRATEGY,
tableName: importedTableName,
Expand Down
4 changes: 2 additions & 2 deletions packages/backend-data/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ class DataGenerator implements ConstructContainerEntryGenerator {
}

amplifyGraphqlDefinitions.push(
convertSchemaToCDK(
convertSchemaToCDK({
schema,
backendSecretResolver,
stableBackendIdentifiers,
importedTableName,
),
}),
);
});
} catch (error) {
Expand Down
1 change: 1 addition & 0 deletions packages/backend-data/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,5 @@ export type DataLogLevel = Extract<
export type AmplifyGen1DynamoDbTableMapping = {
branchName: string;
modelNameToTableNameMapping?: Record<string, string>;
shouldAdoptExistingTable?: boolean;
};
Loading