From e26153d93a8a8def77a47b4de3ee2672ef08a709 Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Sun, 10 Oct 2021 21:11:34 -0700 Subject: [PATCH 1/2] fix: api containers on repushing does not fail --- .../awscloudformation/base-api-stack.ts | 4 +++- .../utils/containers-artifacts.ts | 1 + packages/amplify-e2e-core/src/categories/api.ts | 15 ++++++++++++++- .../src/__tests__/containers-api.test.ts | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts index 6f886524e54..7eecf409af3 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts @@ -52,6 +52,7 @@ export type ContainersStackProps = Readonly<{ createCloudMapService?: boolean; gitHubSourceActionInfo?: GitHubSourceActionInfo; existingEcrRepositories: Set; + currentStackName: string; }>; export abstract class ContainersStack extends cdk.Stack { protected readonly vpcId: string; @@ -240,6 +241,7 @@ export abstract class ContainersStack extends cdk.Stack { taskPorts, isInitialDeploy, desiredCount, + currentStackName, createCloudMapService, } = this.props; @@ -313,7 +315,7 @@ export abstract class ContainersStack extends cdk.Stack { if (build) { const logicalId = `${name}Repository`; - const repositoryName = `${this.envName}-${categoryName}-${apiName}-${name}`; + const repositoryName = `${currentStackName}-${categoryName}-${apiName}-${name}`; if (this.props.existingEcrRepositories.has(repositoryName)) { repository = ecr.Repository.fromRepositoryName(this, logicalId, repositoryName); diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/containers-artifacts.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/containers-artifacts.ts index 7ed760fa8f5..51da9da2da7 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/containers-artifacts.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/utils/containers-artifacts.ts @@ -99,6 +99,7 @@ export async function generateContainersArtifacts( isInitialDeploy, desiredCount, restrictAccess, + currentStackName: envName, apiType, exposedContainer, secretsArns, diff --git a/packages/amplify-e2e-core/src/categories/api.ts b/packages/amplify-e2e-core/src/categories/api.ts index ac22e5c0996..8185d53fd36 100644 --- a/packages/amplify-e2e-core/src/categories/api.ts +++ b/packages/amplify-e2e-core/src/categories/api.ts @@ -1,5 +1,6 @@ import { getCLIPath, updateSchema, nspawn as spawn, KEY_DOWN_ARROW } from '..'; import * as fs from 'fs-extra'; +import * as path from 'path'; import { selectRuntime, selectTemplate } from './lambda-function'; import { singleSelect, multiSelect } from '../utils/selectors'; import _ from 'lodash'; @@ -590,6 +591,18 @@ export function addRestContainerApiForCustomPolicies(projectDir: string, setting .wait('Select which container is the entrypoint') .sendCarriageReturn() .wait('"amplify publish" will build all your local backend and frontend resources') - .run((err: Error) => err ? reject(err) : resolve()); + .run((err: Error) => (err ? reject(err) : resolve())); }); } + +export function modifyRestAPI(projectDir: string, apiName: string) { + const indexFilePath = path.join(projectDir, 'amplify', 'backend', 'api', apiName, 'src', 'express', 'index.js'); + const filesString = fs.readFileSync(indexFilePath, { encoding: 'utf8' }); + const fileLines = filesString.split(EOL); + const index = fileLines.findIndex(r => r === '// Error middleware must be defined last'); + fs.writeFileSync(indexFilePath, fileLines.slice(0, index - 1).join(EOL)); + fs.appendFileSync(indexFilePath, EOL + "app.put('/post', async(req, res, next) => {\ + return {};\ +});" + EOL); + fs.appendFileSync(indexFilePath, fileLines.slice(index, fileLines.length).join(EOL)); +} diff --git a/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts b/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts index 17b4b4059fa..d7485fba538 100644 --- a/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts @@ -6,6 +6,8 @@ import { deleteProject, deleteProjectDir, initJSProjectWithProfile, + getProjectMeta, + modifyRestAPI, } from 'amplify-e2e-core'; import fetch from 'node-fetch'; import { getAWSExports } from '../aws-exports/awsExports'; @@ -44,4 +46,16 @@ describe('amplify api add', () => { const result = await (await fetch(`${endpoint}/images`)).text(); expect(result).toEqual('Processing images...'); }); + + it('init project, enable containers and add multicontainer api push, edit and push', async () => { + const envName = 'devtest'; + await initJSProjectWithProfile(projRoot, { name: 'multicontainer', envName }); + await setupAmplifyProject(projRoot); + await addRestContainerApi(projRoot); + await amplifyPushWithoutCodegen(projRoot); + const meta = await getProjectMeta(projRoot); + const apiName = Object.keys(meta['api'])[0]; + await modifyRestAPI(projRoot, apiName); + await amplifyPushWithoutCodegen(projRoot); + }); }); From 05ea0a8f68b85ec734da6c6e8f06edcde23c9142 Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Tue, 12 Oct 2021 12:12:31 -0700 Subject: [PATCH 2/2] refactor: pr feedback --- .../amplify-e2e-core/src/categories/api.ts | 10 +- .../resources/modified-api-index.ts | 100 ++++++++++++++++++ .../src/__tests__/containers-api.test.ts | 2 +- 3 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 packages/amplify-e2e-core/src/categories/resources/modified-api-index.ts diff --git a/packages/amplify-e2e-core/src/categories/api.ts b/packages/amplify-e2e-core/src/categories/api.ts index 8185d53fd36..141d7e07da8 100644 --- a/packages/amplify-e2e-core/src/categories/api.ts +++ b/packages/amplify-e2e-core/src/categories/api.ts @@ -5,6 +5,7 @@ import { selectRuntime, selectTemplate } from './lambda-function'; import { singleSelect, multiSelect } from '../utils/selectors'; import _ from 'lodash'; import { EOL } from 'os'; +import { modifiedApi } from './resources/modified-api-index'; export function getSchemaPath(schemaName: string): string { return `${__dirname}/../../../amplify-e2e-tests/schemas/${schemaName}`; @@ -597,12 +598,5 @@ export function addRestContainerApiForCustomPolicies(projectDir: string, setting export function modifyRestAPI(projectDir: string, apiName: string) { const indexFilePath = path.join(projectDir, 'amplify', 'backend', 'api', apiName, 'src', 'express', 'index.js'); - const filesString = fs.readFileSync(indexFilePath, { encoding: 'utf8' }); - const fileLines = filesString.split(EOL); - const index = fileLines.findIndex(r => r === '// Error middleware must be defined last'); - fs.writeFileSync(indexFilePath, fileLines.slice(0, index - 1).join(EOL)); - fs.appendFileSync(indexFilePath, EOL + "app.put('/post', async(req, res, next) => {\ - return {};\ -});" + EOL); - fs.appendFileSync(indexFilePath, fileLines.slice(index, fileLines.length).join(EOL)); + fs.writeFileSync(indexFilePath, modifiedApi); } diff --git a/packages/amplify-e2e-core/src/categories/resources/modified-api-index.ts b/packages/amplify-e2e-core/src/categories/resources/modified-api-index.ts new file mode 100644 index 00000000000..9e0d0177bb0 --- /dev/null +++ b/packages/amplify-e2e-core/src/categories/resources/modified-api-index.ts @@ -0,0 +1,100 @@ +export const modifiedApi = `const express = require("express"); +const bodyParser = require('body-parser'); +const port = process.env.PORT || 3001; + +const { + addPostToDDB, + scanPostsFromDDB, + getPostFromDDB +} = require('./DynamoDBActions'); + +const app = express(); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); + +// Enable CORS for all methods +app.use(function (req, res, next) { + res.header("Access-Control-Allow-Origin", "*") + res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") + next() +}); + +const checkAuthRules = (req, res, next) => { + const jwt = req.header("Authorization") || ""; + + const [, jwtBody] = jwt.split("."); + + const obj = JSON.parse( + jwtBody ? Buffer.from(jwtBody, "base64").toString("utf-8") : "{}" + ); + + //Customer can perform logic on JWT body + //console.log(obj); + next(); + + //Failure example: + // const err = new Error("Access denied"); + // err.statusCode = 403; + // return next(err); +} + +app.use(checkAuthRules); + +app.get("/posts", async (req, res, next) => { + + try { + const result = await scanPostsFromDDB(); + res.contentType("application/json").send(result); + } catch (err) { + next(err); + } +}); + +app.get("/post", async (req, res, next) => { + console.log(req.query.id); + + try { + const result = await getPostFromDDB(req.query.id); + res.contentType("application/json").send(result); + } catch (err) { + next(err); + } +}); + +app.post("/post", async (req, res, next) => { + + try { + const result = await addPostToDDB(req.body); + res.contentType("application/json").send(result); + } catch (err) { + next(err); + } +}); + +app.put('/post', async(req, res, next) => { + return {}; +}); + +app.use((req, res, next) => { + + try { + const result = \`Please try GET on /posts, /post?id=xyz, or a POST to /post with JSON {\"id\":\"123\",\"title\":\"Fargate test\"}\`; + res.contentType("application/json").send(result); + } catch (err) { + next(err); + } +}); + +// Error middleware must be defined last +app.use((err, req, res, next) => { + console.error(err.message); + if (!err.statusCode) err.statusCode = 500; // If err has no specified error code, set error code to 'Internal Server Error (500)' + res + .status(err.statusCode) + .json({ message: err.message }) + .end(); +}); + +app.listen(port, () => { + console.log('Example app listening at http://localhost:' + port); +});`; diff --git a/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts b/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts index d7485fba538..8e728cdff63 100644 --- a/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/containers-api.test.ts @@ -55,7 +55,7 @@ describe('amplify api add', () => { await amplifyPushWithoutCodegen(projRoot); const meta = await getProjectMeta(projRoot); const apiName = Object.keys(meta['api'])[0]; - await modifyRestAPI(projRoot, apiName); + modifyRestAPI(projRoot, apiName); await amplifyPushWithoutCodegen(projRoot); }); });