diff --git a/checkout/package-lock.json b/checkout/package-lock.json index 478d5b6..81d9701 100644 --- a/checkout/package-lock.json +++ b/checkout/package-lock.json @@ -1594,7 +1594,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1615,12 +1616,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1635,17 +1638,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1762,7 +1768,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1774,6 +1781,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1788,6 +1796,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1795,12 +1804,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1819,6 +1830,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1899,7 +1911,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1911,6 +1924,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1996,7 +2010,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2032,6 +2047,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2051,6 +2067,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2094,12 +2111,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -2171,9 +2190,9 @@ "dev": true }, "handlebars": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.2.tgz", - "integrity": "sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", + "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", "dev": true, "requires": { "neo-async": "^2.6.0", diff --git a/checkout/src/products/handlers/create.js b/checkout/src/products/handlers/create.js new file mode 100644 index 0000000..a17b01f --- /dev/null +++ b/checkout/src/products/handlers/create.js @@ -0,0 +1,34 @@ +const dynamodb = require("aws-sdk/clients/dynamodb"); +const uuid = require("uuid/v4"); +const docClient = new dynamodb.DocumentClient(); +const tableName = process.env.SAMPLE_TABLE; + +exports.createProductHandler = async event => { + try { + if (event.httpMethod !== "POST") { + throw new Error( + `Create product only accepts POST method, you tried: ${event.httpMethod} method.` + ); + } + + const body = JSON.parse(event.body); + body.id = uuid(); + const Item = Object.assign({}, body); + + var params = { + TableName: tableName, + Item + }; + + await docClient.put(params).promise(); + const response = { + statusCode: 201, + headers: { + "Access-Control-Allow-Origin": "*" + } + }; + return response; + } catch (error) { + return error; + } +}; diff --git a/checkout/src/products/handlers/delete.js b/checkout/src/products/handlers/delete.js new file mode 100644 index 0000000..d266ac2 --- /dev/null +++ b/checkout/src/products/handlers/delete.js @@ -0,0 +1,35 @@ +const dynamodb = require("aws-sdk/clients/dynamodb"); +const db = new dynamodb.DocumentClient(); +const tableName = process.env.SAMPLE_TABLE; + +module.exports.deleteProduct = async event => { + try { + if (event.httpMethod !== "DELETE") { + throw new Error( + `delete product only accepts GET method, you tried: ${event.httpMethod} method.` + ); + } + + const id = event.pathParameters.id; + + const params = { + TableName: tableName, + Key: { + id: id + } + }; + + await db.delete(params).promise(); + + const response = { + statusCode: 200, + headers: { + "Access-Control-Allow-Origin": "*" + } + }; + + return response; + } catch (error) { + return error; + } +}; diff --git a/checkout/src/products/handlers/get-all-mocking.js b/checkout/src/products/handlers/get-all-mocking.js deleted file mode 100644 index f66bc74..0000000 --- a/checkout/src/products/handlers/get-all-mocking.js +++ /dev/null @@ -1,60 +0,0 @@ -exports.getAllProductsMockHandler = async(event) => { - if (event.httpMethod !== 'GET') { - throw new Error(`getAllItems only accept GET method, you tried: ${event.httpMethod}`); - } - - const products = [{ - id: 0, - name: 'Suco de uva tinto integral aliança garrafa 1l', - brand: 'Aliança', - description: 'Garrafa 1 litro', - price: 13.96 - }, - { - id: 1, - name: 'Suco do bem todo dia caju 200ml', - brand: 'Do Bem', - description: 'Caixa 200ml', - price: 1.66 - }, - { - id: 2, - name: 'Suco maratá uva embalagem 200ml', - brand: 'Maratá', - description: 'Embalagem 200ml', - price: 1.90 - }, - { - id: 3, - name: 'Suco pronto Del Valle fresh limão 250ml', - brand: 'Del Valle', - description: 'Pet 250ml', - price: 2.34 - }, - { - id: 4, - name: 'Suco pronto jandaia caju caixa 1l', - brand: 'Jandaia', - description: 'Caixa 1 litro', - price: 6.59 - }, - { - id: 5, - name: 'Suco pronto tampico uva garrafa 330ml', - brand: 'Tampico', - description: 'Garrafa 330ml', - price: 1.96 - } - ] - - const response = { - statusCode: 200, - headers: { - "Access-Control-Allow-Origin": "*" - }, - body: JSON.stringify(products) - }; - - console.info(`response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}`); - return response; -} \ No newline at end of file diff --git a/checkout/src/products/handlers/get-all.js b/checkout/src/products/handlers/get-all.js new file mode 100755 index 0000000..7a62269 --- /dev/null +++ b/checkout/src/products/handlers/get-all.js @@ -0,0 +1,31 @@ +const tableName = process.env.SAMPLE_TABLE; +const dynamodb = require("aws-sdk/clients/dynamodb"); +const docClient = new dynamodb.DocumentClient(); + +exports.getAllHandler = async event => { + if (event.httpMethod !== "GET") { + throw new Error( + `getAllProducts only accept GET method, you tried: ${event.httpMethod}` + ); + } + + var params = { + TableName: tableName + }; + + const data = await docClient.scan(params).promise(); + const items = data.Items; + + const response = { + statusCode: 200, + body: JSON.stringify(items), + headers: { + "Access-Control-Allow-Origin": "*" + } + }; + + console.info( + `response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}` + ); + return response; +}; diff --git a/checkout/src/products/handlers/get-by-id.js b/checkout/src/products/handlers/get-by-id.js new file mode 100644 index 0000000..7f2aca6 --- /dev/null +++ b/checkout/src/products/handlers/get-by-id.js @@ -0,0 +1,33 @@ +const tableName = process.env.SAMPLE_TABLE; +const dynamodb = require("aws-sdk/clients/dynamodb"); +const docClient = new dynamodb.DocumentClient(); + +exports.getByIdHandler = async event => { + if (event.httpMethod !== "GET") { + throw new Error( + `getMethod only accept GET method, you tried: ${event.httpMethod}` + ); + } + + const id = event.pathParameters.id; + + const params = { + TableName: tableName, + Key: { id: id } + }; + + const data = await docClient.scan(params).promise(); + const item = data.Item; + + const response = { + statusCode: 200, + body: JSON.stringify(item), + headers: { + "Access-Control-Allow-Origin": "*" + } + }; + console.info( + `response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}` + ); + return response; +}; diff --git a/checkout/src/sales/handlers/create.js b/checkout/src/sales/handlers/create.js old mode 100644 new mode 100755 index 8c3c33e..4f79655 --- a/checkout/src/sales/handlers/create.js +++ b/checkout/src/sales/handlers/create.js @@ -1,45 +1,38 @@ -const dynamodb = require('aws-sdk/clients/dynamodb'); -const uuid = require('uuid/v4'); +const dynamodb = require("aws-sdk/clients/dynamodb"); +const uuid = require("uuid/v4"); const docClient = new dynamodb.DocumentClient(); const tableName = process.env.SAMPLE_TABLE; -exports.createSaleHandler = async(event) => { - try { - if (event.httpMethod !== 'POST') { - throw new Error(`postMethod only accepts POST method, you tried: ${event.httpMethod} method.`); - } - - console.info('received:', event); - - const body = JSON.parse(event.body); - body.id = uuid(); - const Item = Object.assign({}, body); +exports.createSaleHandler = async event => { + try { + if (event.httpMethod !== "POST") { + throw new Error( + `createSale only accepts POST method, you tried: ${event.httpMethod} method.` + ); + } - var params = { - TableName: tableName, - Item - }; + const body = JSON.parse(event.body); + body.id = uuid(); + const Item = Object.assign({}, body); - const { requestContext } = event; - const Location = !!requestContext ? `https://${requestContext.domainName}${requestContext.path}/${body.id}` : body.id; - const result = await docClient.put(params).promise(); - const response = { - statusCode: 201, - headers: { - Location, - "Access-Control-Allow-Origin": "*" - } - }; + var params = { + TableName: tableName, + Item + }; - return response; - } catch (error) { - console.log('error %j', error); - const response = { - statusCode: 500, - headers: { - "Access-Control-Allow-Origin": "*" - }, - body: JSON.stringify(error) - } - return response; - } -} \ No newline at end of file + const { requestContext } = event; + const Location = !!requestContext + ? `https://${requestContext.domainName}${requestContext.path}/${body.id}` + : body.id; + const result = await docClient.put(params).promise(); + const response = { + statusCode: 201, + headers: { + Location, + "Access-Control-Allow-Origin": "*" + } + }; + return response; + } catch (error) { + return error; + } +}; diff --git a/checkout/src/sales/handlers/delete.js b/checkout/src/sales/handlers/delete.js new file mode 100644 index 0000000..6322302 --- /dev/null +++ b/checkout/src/sales/handlers/delete.js @@ -0,0 +1,35 @@ +const dynamodb = require("aws-sdk/clients/dynamodb"); +const db = new dynamodb.DocumentClient(); +const tableName = process.env.SAMPLE_TABLE; + +module.exports.deleteSale = async event => { + try { + if (event.httpMethod !== "DELETE") { + throw new Error( + `deleteSales only accepts GET method, you tried: ${event.httpMethod} method.` + ); + } + + const id = event.pathParameters.id; + + const params = { + TableName: tableName, + Key: { + id: id + } + }; + + const result = await db.delete(params).promise(); + + const response = { + statusCode: 200, + headers: { + "Access-Control-Allow-Origin": "*" + } + }; + + return response; + } catch (error) { + return error; + } +}; diff --git a/checkout/src/sales/handlers/get-all.js b/checkout/src/sales/handlers/get-all.js old mode 100644 new mode 100755 index 6ddc7f5..00c68dd --- a/checkout/src/sales/handlers/get-all.js +++ b/checkout/src/sales/handlers/get-all.js @@ -1,28 +1,32 @@ const tableName = process.env.SAMPLE_TABLE; -const dynamodb = require('aws-sdk/clients/dynamodb'); +const dynamodb = require("aws-sdk/clients/dynamodb"); const docClient = new dynamodb.DocumentClient(); -exports.getAllHandler = async(event) => { - if (event.httpMethod !== 'GET') { - throw new Error(`getAllItems only accept GET method, you tried: ${event.httpMethod}`); - } +exports.getAllHandler = async event => { + if (event.httpMethod !== "GET") { + throw new Error( + `getAllItems only accept GET method, you tried: ${event.httpMethod}` + ); + } - console.info('received:', event); - var params = { - TableName: tableName - }; + console.info("received:", event); + var params = { + TableName: tableName + }; - const data = await docClient.scan(params).promise(); - const items = data.Items; + const data = await docClient.scan(params).promise(); + const items = data.Items; - const response = { - statusCode: 200, - body: JSON.stringify(items), - headers: { - "Access-Control-Allow-Origin": "*" - } - }; + const response = { + statusCode: 200, + body: JSON.stringify(items), + headers: { + "Access-Control-Allow-Origin": "*" + } + }; - console.info(`response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}`); - return response; -} \ No newline at end of file + console.info( + `response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}` + ); + return response; +}; diff --git a/checkout/src/sales/handlers/get-by-id.js b/checkout/src/sales/handlers/get-by-id.js old mode 100644 new mode 100755 diff --git a/checkout/template.yml b/checkout/template.yml index 084de1a..e208f44 100644 --- a/checkout/template.yml +++ b/checkout/template.yml @@ -3,7 +3,7 @@ Description: >- Checkout serverless api Transform: -- AWS::Serverless-2016-10-31 + - AWS::Serverless-2016-10-31 Parameters: UserPoolArn: @@ -29,7 +29,134 @@ Resources: Identity: Header: Authorization AddDefaultAuthorizerToCorsPreflight: False - + + getAllProductsFunction: + Type: AWS::Serverless::Function + Properties: + Handler: src/products/handlers/get-all.getAllHandler + Runtime: nodejs10.x + MemorySize: 128 + Timeout: 100 + Description: All products + Events: + GetAllProductsResource: + Type: Api + Properties: + RestApiId: !Ref DevAcademyApi + Path: products + Method: GET + Auth: + Authorizer: CognitoAuthorizer + getAllProductsLambdaPermission: + Type: AWS::Lambda::Permission + DependsOn: + - DevAcademyApi + - getAllProductsFunction + Properties: + Action: lambda:InvokeFunction + FunctionName: !Ref getAllProductsFunction + Principal: apigateway.amazonaws.com + + getProductByIdFunction: + Type: AWS::Serverless::Function + Properties: + Handler: src/products/handlers/get-by-id.getByIdHandler + Runtime: nodejs10.x + MemorySize: 128 + Timeout: 100 + Description: Get Product by id from dynamodb table + Policies: + - DynamoDBCrudPolicy: + TableName: !Ref ProductsTable + Environment: + Variables: + SAMPLE_TABLE: !Ref ProductsTable + Events: + GetProductByIdResource: + Type: Api + Properties: + RestApiId: !Ref DevAcademyApi + Path: products/{id} + Method: GET + Auth: + Authorizer: CognitoAuthorizer + + getProductByIdLambdaPermission: + Type: AWS::Lambda::Permission + DependsOn: + - DevAcademyApi + - getProductByIdFunction + Properties: + Action: lambda:InvokeFunction + FunctionName: !Ref getProductByIdFunction + Principal: apigateway.amazonaws.com + + createProductFunction: + Type: AWS::Serverless::Function + Properties: + Handler: src/products/handlers/create.createProductHandler + Runtime: nodejs10.x + MemorySize: 128 + Timeout: 100 + Description: Create product in dynamodb + Policies: + - DynamoDBCrudPolicy: + TableName: !Ref ProductsTable + Environment: + Variables: + SAMPLE_TABLE: !Ref ProductsTable + Events: + CreateProductResource: + Type: Api + Properties: + RestApiId: !Ref DevAcademyApi + Path: products + Method: POST + Auth: + Authorizer: CognitoAuthorizer + createProductLambdaPermission: + Type: AWS::Lambda::Permission + DependsOn: + - DevAcademyApi + - createProductFunction + Properties: + Action: lambda:InvokeFunction + FunctionName: !Ref createProductFunction + Principal: apigateway.amazonaws.com + + deleteProductFunction: + Type: AWS::Serverless::Function + Properties: + Handler: src/products/handlers/delete.deleteProductHandler + Runtime: nodejs10.x + MemorySize: 128 + Timeout: 100 + Description: Delete product in dynamodb + Policies: + - DynamoDBCrudPolicy: + TableName: !Ref ProductsTable + Environment: + Variables: + SAMPLE_TABLE: !Ref ProductsTable + Events: + DeleteProductResource: + Type: Api + Properties: + RestApiId: !Ref DevAcademyApi + Path: products/{id} + Method: DELETE + Auth: + Authorizer: CognitoAuthorizer + deleteProductLambdaPermission: + Type: AWS::Lambda::Permission + DependsOn: + - DevAcademyApi + - deleteProductFunction + Properties: + Action: lambda:InvokeFunction + FunctionName: !Ref deleteProductFunction + Principal: apigateway.amazonaws.com + getAllSalesFunction: Type: AWS::Serverless::Function Properties: @@ -41,10 +168,10 @@ Resources: Description: Get all sales from dynamodb table Policies: - DynamoDBCrudPolicy: - TableName: !Ref VendasTable + TableName: !Ref SalesTable Environment: Variables: - SAMPLE_TABLE: !Ref VendasTable + SAMPLE_TABLE: !Ref SalesTable Events: GetAllSalesResource: Type: Api @@ -57,8 +184,8 @@ Resources: getAllSalesLambdaPermission: Type: AWS::Lambda::Permission DependsOn: - - DevAcademyApi - - getAllSalesFunction + - DevAcademyApi + - getAllSalesFunction Properties: Action: lambda:InvokeFunction FunctionName: !Ref getAllSalesFunction @@ -74,10 +201,10 @@ Resources: Description: Get sale by id from dynamodb table Policies: - DynamoDBCrudPolicy: - TableName: !Ref VendasTable + TableName: !Ref SalesTable Environment: Variables: - SAMPLE_TABLE: !Ref VendasTable + SAMPLE_TABLE: !Ref SalesTable Events: GetSaleResource: Type: Api @@ -90,8 +217,8 @@ Resources: getSaleByIdLambdaPermission: Type: AWS::Lambda::Permission DependsOn: - - DevAcademyApi - - getSaleByIdFunction + - DevAcademyApi + - getSaleByIdFunction Properties: Action: lambda:InvokeFunction FunctionName: !Ref getSaleByIdFunction @@ -107,10 +234,10 @@ Resources: Description: Create sale in dynamodb Policies: - DynamoDBCrudPolicy: - TableName: !Ref VendasTable + TableName: !Ref SalesTable Environment: Variables: - SAMPLE_TABLE: !Ref VendasTable + SAMPLE_TABLE: !Ref SalesTable Events: CreateSaleResource: Type: Api @@ -123,66 +250,57 @@ Resources: createSaleLambdaPermission: Type: AWS::Lambda::Permission DependsOn: - - DevAcademyApi - - createSaleFunction + - DevAcademyApi + - createSaleFunction Properties: Action: lambda:InvokeFunction FunctionName: !Ref createSaleFunction Principal: apigateway.amazonaws.com - getAllProductsMockFunction: + deleteSaleFunction: Type: AWS::Serverless::Function Properties: - Handler: src/products/handlers/get-all-mocking.getAllProductsMockHandler + Handler: src/sales/handlers/delete.deleteSaleHandler Runtime: nodejs10.x MemorySize: 128 Timeout: 100 - Description: All products mock + Description: Delete sale in dynamodb + Policies: + - DynamoDBCrudPolicy: + TableName: !Ref SalesTable + Environment: + Variables: + SAMPLE_TABLE: !Ref SalesTable Events: - GetAllProductsMockResource: + DeleteSaleResource: Type: Api Properties: RestApiId: !Ref DevAcademyApi - Path: products/mock - Method: GET + Path: sales/{id} + Method: DELETE Auth: Authorizer: CognitoAuthorizer - getAllProductsLambdaPermission: + deleteSaleLambdaPermission: Type: AWS::Lambda::Permission DependsOn: - - DevAcademyApi - - getAllProductsMockFunction + - DevAcademyApi + - deleteSaleFunction Properties: Action: lambda:InvokeFunction - FunctionName: !Ref getAllProductsMockFunction + FunctionName: !Ref deleteSaleFunction Principal: apigateway.amazonaws.com - getAllProductsUnauthMockFunction: - Type: AWS::Serverless::Function - Properties: - Handler: src/products/handlers/get-all-mocking.getAllProductsMockHandler - Runtime: nodejs10.x - MemorySize: 128 - Timeout: 100 - Description: All products mock - Events: - GetAllProductsMockResource: - Type: Api - Properties: - RestApiId: !Ref DevAcademyApi - Path: /unauth/products/mock - Method: GET - getAllProductsUnauthLambdaPermission: - Type: AWS::Lambda::Permission - DependsOn: - - DevAcademyApi - - getAllProductsUnauthMockFunction + SalesTable: + Type: AWS::Serverless::SimpleTable Properties: - Action: lambda:InvokeFunction - FunctionName: !Ref getAllProductsUnauthMockFunction - Principal: apigateway.amazonaws.com - - VendasTable: + PrimaryKey: + Name: id + Type: String + ProvisionedThroughput: + ReadCapacityUnits: 2 + WriteCapacityUnits: 2 + + ProductsTable: Type: AWS::Serverless::SimpleTable Properties: PrimaryKey: @@ -190,4 +308,4 @@ Resources: Type: String ProvisionedThroughput: ReadCapacityUnits: 2 - WriteCapacityUnits: 2 \ No newline at end of file + WriteCapacityUnits: 2 diff --git a/config.sh b/config.sh index e24d53f..d9d4e7f 100644 --- a/config.sh +++ b/config.sh @@ -1,3 +1,4 @@ # teu-bucket-no-s3 -sam package --s3-bucket=teu-bucket-no-s3 --template-file=./template.yml --output-template-file=./template-export.yml --region=us-east-1 + +sam package --s3-bucket=cf-templates-7pq8y5kaylh0-us-east-1 --template-file=./template.yml --output-template-file=./template-export.yml --region=us-east-1 aws cloudformation deploy --template-file ./template-export.yml --stack-name dev-academy-sales --region us-east-1 --capabilities CAPABILITY_IAM