Update workflow
Update workflow
- Return to the command line interface of the Cloud9 instance, replace the contents of the functions/account-applications/flag.js file with the content below.
- Press Ctrl + S to save changes.
'use strict';
const REGION = process.env.REGION
const APPLICATIONS_TABLE_NAME = process.env.APPLICATIONS_TABLE_NAME
const AWS = require('aws-sdk')
AWS.config.update({region: REGION});
const dynamo = new AWS.DynamoDB.DocumentClient();
const AccountApplications = require('./AccountApplications')(APPLICATIONS_TABLE_NAME, dynamo)
const flagForReview = async (data) => {
const { id, flagType, taskToken } = data
if (flagType !== 'REVIEW' && flagType !== 'UNPROCESSABLE_DATA') {
throw new Error("flagType must be REVIEW or UNPROCESSABLE_DATA")
}
let newState
let reason
if (flagType === 'REVIEW') {
newState = 'FLAGGED_FOR_REVIEW'
reason = data.reason
}
else {
reason = JSON.parse(data.errorInfo.Cause).errorMessage
newState = 'FLAGGED_WITH_UNPROCESSABLE_DATA'
}
const updatedApplication = await AccountApplications.update(
id,
{
state: newState,
reason,
taskToken
}
)
return updatedApplication
}
module.exports.handler = async(event) => {
try {
const result = await flagForReview(event)
return result
} catch (ex) {
console.error(ex)
console.info('event', JSON.stringify(event))
throw ex
}
};
- Run the command below to create a new file review.js
touch functions/account-applications/review.js
- Replace the contents of the file functions/account-applications/review.js with the content below.
- Press Ctrl + S to save changes.
'use strict';
const REGION = process.env.REGION
const APPLICATIONS_TABLE_NAME = process.env.APPLICATIONS_TABLE_NAME
const AWS = require('aws-sdk')
AWS.config.update({region: REGION});
const dynamo = new AWS.DynamoDB.DocumentClient();
const stepfunctions = new AWS.StepFunctions();
const AccountApplications = require('./AccountApplications')(APPLICATIONS_TABLE_NAME, dynamo)
const updateApplicationWithDecision = (id, decision) => {
if (decision !== 'APPROVE' && decision !== 'REJECT') {
throw new Error("Required `decision` parameter must be 'APPROVE' or 'REJECT'")
}
switch(decision) {
case 'APPROVE': return AccountApplications.update(id, { state: 'REVIEW_APPROVED' })
case 'REJECT': return AccountApplications.update(id, { state: 'REVIEW_REJECTED' })
}
}
const updateWorkflowWithReviewDecision = async (data) => {
const { id, decision } = data
const updatedApplication = await updateApplicationWithDecision(id, decision)
let params = {
output: JSON.stringify({ decision }),
taskToken: updatedApplication.taskToken
};
await stepfunctions.sendTaskSuccess(params).promise()
return updatedApplication
}
module.exports.handler = async(event) => {
try {
const result = await updateWorkflowWithReviewDecision(event)
return result
} catch (ex) {
console.error(ex)
console.info('event', JSON.stringify(event))
throw ex
}
};
- Replace the content of the file template.yaml with the content below.
- Press Ctrl + S to save changes.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Template for step-functions-workshop
Resources:
ApplicationProcessingStateMachine:
Type: AWS::Serverless::StateMachine
Properties:
DefinitionUri: statemachine/account-application-workflow.asl.json
DefinitionSubstitutions:
DataCheckingFunctionArn: !GetAtt DataCheckingFunction.Arn
FlagApplicationFunctionName: !Ref FlagApplicationFunction
Policies:
- LambdaInvokePolicy:
FunctionName: !Ref DataCheckingFunction
- LambdaInvokePolicy:
FunctionName: !Ref FlagApplicationFunction
ApproveApplicationFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sfn-workshop-ApproveApplication
CodeUri: functions/account-applications/
Handler: approve.handler
Runtime: nodejs12.x
Environment:
Variables:
APPLICATIONS_TABLE_NAME: !Ref ApplicationsTable
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ApplicationsTable
DataCheckingFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sfn-workshop-DataChecking
CodeUri: functions/data-checking/
Handler: data-checking.handler
Runtime: nodejs12.x
FindApplicationsFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sfn-workshop-FindApplications
CodeUri: functions/account-applications/
Handler: find.handler
Runtime: nodejs12.x
Environment:
Variables:
APPLICATIONS_TABLE_NAME: !Ref ApplicationsTable
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ApplicationsTable
FlagApplicationFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sfn-workshop-FlagApplication
CodeUri: functions/account-applications/
Handler: flag.handler
Runtime: nodejs12.x
Environment:
Variables:
APPLICATIONS_TABLE_NAME: !Ref ApplicationsTable
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ApplicationsTable
RejectApplicationFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sfn-workshop-RejectApplication
CodeUri: functions/account-applications/
Handler: reject.handler
Runtime: nodejs12.x
Environment:
Variables:
APPLICATIONS_TABLE_NAME: !Ref ApplicationsTable
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ApplicationsTable
ReviewApplicationFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sfn-workshop-ReviewApplication
CodeUri: functions/account-applications/
Handler: review.handler
Runtime: nodejs12.x
Environment:
Variables:
APPLICATIONS_TABLE_NAME: !Ref ApplicationsTable
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ApplicationsTable
- Statement:
- Sid: AllowCallbacksToStateMachinePolicy
Effect: "Allow"
Action:
- "states:SendTaskSuccess"
- "states:SendTaskFailure"
Resource: !Ref ApplicationProcessingStateMachine
SubmitApplicationFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sfn-workshop-SubmitApplication
CodeUri: functions/account-applications/
Handler: submit.handler
Runtime: nodejs12.x
Environment:
Variables:
APPLICATIONS_TABLE_NAME: !Ref ApplicationsTable
APPLICATION_PROCESSING_STEP_FUNCTION_ARN: !Ref ApplicationProcessingStateMachine
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ApplicationsTable
- StepFunctionsExecutionPolicy:
StateMachineName: !GetAtt ApplicationProcessingStateMachine.Name
ApplicationsTable:
Type: 'AWS::DynamoDB::Table'
Properties:
TableName: !Sub StepFunctionWorkshop-AccountApplications-${AWS::StackName}
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
-
AttributeName: state
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
BillingMode: PAY_PER_REQUEST
GlobalSecondaryIndexes:
-
IndexName: state
KeySchema:
-
AttributeName: state
KeyType: HASH
Projection:
ProjectionType: ALL
Outputs:
SubmitApplicationFunctionArn:
Description: "Submit Application Function ARN"
Value: !GetAtt SubmitApplicationFunction.Arn
FlagApplicationFunctionArn:
Description: "Flag Application Function ARN"
Value: !GetAtt FlagApplicationFunction.Arn
FindApplicationsFunctionArn:
Description: "Find Applications Function ARN"
Value: !GetAtt FindApplicationsFunction.Arn
ApproveApplicationFunctionArn:
Description: "Approve Application Function ARN"
Value: !GetAtt ApproveApplicationFunction.Arn
RejectApplicationFunctionArn:
Description: "Reject Application Function ARN"
Value: !GetAtt RejectApplicationFunction.Arn
DataCheckingFunctionArn:
Description: "Data Checking Function ARN"
Value: !GetAtt DataCheckingFunction.Arn
- Replace the contents of the file statemachine/account-application-workflow.asl.json with the content below.
- Press Ctrl + S to save changes.
{
"StartAt": "Check Name",
"States": {
"Check Name": {
"Type": "Task",
"Parameters": {
"command": "CHECK_NAME",
"data": {
"name.$": "$.application.name"
}
},
"Resource": "${DataCheckingFunctionArn}",
"ResultPath": "$.checks.name",
"Next": "Check Address"
},
"Check Address": {
"Type": "Task",
"Parameters": {
"command": "CHECK_ADDRESS",
"data": {
"address.$": "$.application.address"
}
},
"Resource": "${DataCheckingFunctionArn}",
"ResultPath": "$.checks.address",
"Next": "Review Required?"
},
"Review Required?": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.checks.name.flagged",
"BooleanEquals": true,
"Next": "Pending Review"
},
{
"Variable": "$.checks.address.flagged",
"BooleanEquals": true,
"Next": "Pending Review"
}
],
"Default": "Approve Application"
},
"Pending Review": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "${FlagApplicationFunctionName}",
"Payload": {
"id.$": "$.application.id",
"flagType": "REVIEW",
"taskToken.$": "$$.Task.Token"
}
},
"ResultPath": "$.review",
"Next": "Review Approved?"
},
"Review Approved?": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.review.decision",
"StringEquals": "APPROVE",
"Next": "Approve Application"
},
{
"Variable": "$.review.decision",
"StringEquals": "REJECT",
"Next": "Reject Application"
}
]
},
"Reject Application": {
"Type": "Pass",
"End": true
},
"Approve Application": {
"Type": "Pass",
"End": true
}
}
}
- Run the command below to execute the build and deploy, check the deployment is successful before doing the next step:
sam build && sam deploy