使用 Amazon SDK for JavaScript 创建 Amazon 无服务器工作流 - Amazon SDK for JavaScript
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Amazon SDK for JavaScript V3 API 参考指南详细描述了 Amazon SDK for JavaScript 版本 3 (V3) 的所有 API 操作。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Amazon SDK for JavaScript 创建 Amazon 无服务器工作流

您可以通过对 Amazon SDK for Java 和 Amazon Step Functions 使用 Step Functions 来创建 Amazon 无服务器工作流。每个工作流步骤都通过使用 Amazon Lambda 函数实现。Lambda 是一项计算服务,使您无需预置或管理服务器即可运行代码。Step Functions 是一项无服务器编排服务,可让您搭配使用 Lambda 函数和其他 Amazon 服务来构建业务关键型应用程序。

注意

您可以使用各种编程语言创建 Lambda 函数。在本教程中,Lambda 函数是使用 Lambda Java API 实现的。有关 Lambda 的更多信息,请参阅什么是 Lambda

在本教程中,您将创建一个工作流,为组织创建支持工单。每个工作流步骤都会对工单执行一项操作。本教程介绍如何使用 JavaScript 处理工作流数据。例如,您将学习如何读取传递给工作流的数据,如何在步骤之间传递数据,以及如何从工作流调用 Amazon 服务。

完成费用:本文档中包含的 Amazon 服务包含在 Amazon 免费套餐中。

注意:在学习本教程时,请务必终止您创建的所有资源,以确保系统不再向您收费。

先决条件任务

要设置和运行此示例,您必须先完成以下任务:

  • 设置项目环境以运行这些 Node TypeScript 示例,并安装所需的 Amazon SDK for JavaScript 和第三方模块。请按照 GitHub 上的说明进行操作。

  • 使用用户凭证创建共享配置文件。有关提供共享凭证文件的更多信息,请参阅《Amazon SDK 和工具参考指南》中的共享配置和凭证文件

创建 Amazon 资源

本教程要求具有以下资源。

  • 一个名为 Case 的 Amazon DynamoDB 表,其密钥名为 Id

  • 一个名为 lambda-support 的 IAM 角色,用于调用 Lambda 函数。该角色的策略使其能够从 Lambda 函数调用 Amazon DynamoDB 和 Amazon Simple Email Service 服务。

  • 一个名为 workflow-support 的 IAM 角色,用于调用工作流。

  • 一个用于托管 Lambda 函数的 Amazon S3 存储桶。

您可以手动创建这些资源,但我们建议使用本教程中所述的 Amazon Cloud Development Kit (Amazon CDK) (Amazon CDK) 预置这些资源。

使用 Amazon CloudFormation 创建 Amazon 资源

Amazon CloudFormation 让您能够以可预测、可重复的方式创建和预置 Amazon 基础设施部署。有关 Amazon CloudFormation 的更多信息,请参阅 Amazon CloudFormation 用户指南

创建 Amazon CloudFormation 堆栈:

  1. 按照 Amazon CLI 用户指南中的说明安装和配置 Amazon CLI。

  2. 在项目文件夹的根目录中创建一个名为 setup.yaml 的文件,然后将 GitHub 上此处的内容复制到该文件中。

    注意

    Amazon CloudFormation 模板是使用 GitHub 上此处提供的 Amazon CDK 生成的。有关 Amazon CDK 的更多信息,请参阅 Amazon Cloud Development Kit (Amazon CDK) 开发人员指南

  3. 从命令行运行以下命令,将 STACK_NAME 替换为堆栈的唯一名称。

    重要

    在一个 Amazon 区域和一个 Amazon 账户中,堆栈名称必须唯一。您最多可指定 128 个字符,支持数字和连字符。

    aws cloudformation create-stack --stack-name STACK_NAME --template-body file://setup.yaml --capabilities CAPABILITY_IAM

    有关 create-stack 命令参数的更多信息,请参阅 Amazon CLI 命令参考指南Amazon CloudFormation 用户指南

使用 Amazon Web Services 管理控制台创建 Amazon 资源;

要在控制台中为应用程序创建资源,请按照 Amazon CloudFormation 用户指南中的说明进行操作。使用提供的模板创建一个名为 setup.yaml 的文件,然后复制 GitHub 上此处的内容。

重要

在一个 Amazon 区域和一个 Amazon 账户中,堆栈名称必须唯一。您最多可指定 128 个字符,支持数字和连字符。

在 Amazon CloudFormation 仪表板上打开堆栈,然后选择资源选项卡,即可在控制台中查看资源列表。您将在本教程中需要这些内容。

创建工作流

下图显示了您将使用本教程创建的工作流。

以下是工作流中每个步骤中发生的情况:

+ 开始 - 启动工作流。

+ 开立案例 - 通过将支持工单 ID 值传递给工作流来处理该值。

+ 分配案例 - 将支持案例分配给员工,并将数据存储在 DynamoDB 表中。

+ 发送电子邮件 - 使用 Amazon Simple Email Service (Amazon SES) 向员工发送一封电子邮件,告知他们有一张新工单。

+ 结束 - 停止工作流。

使用 Step Functions 创建无服务器工作流

您可以创建处理支持工单的工作流。要使用 Step Functions 定义工作流,您需要创建一个 Amazon States Language(基于 JSON)文档来定义您的状态机。Amazon States Language 文档描述了每个步骤。定义文档后,Step Functions 将提供工作流的可视化表示。下图显示了 Amazon States Language 文档和工作流的可视化表示。

工作流可以在步骤之间传递数据。例如,开立案例步骤处理案例 ID 值(该值传递给工作流),并将该值传递给分配案例步骤。在本教程的后面部分,您将使用 Lambda 函数创建应用程序逻辑来读取和处理数据值。

创建工作流

  1. 打开 Amazon Web Services 控制台

  2. 选择创建状态机

  3. 选择使用代码段创作。在类型区域中,选择标准

  4. 输入以下代码,指定 Amazon States Language 文档。

    { "Comment": "A simple Amazon Step Functions state machine that automates a call center support session.", "StartAt": "Open Case", "States": { "Open Case": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "Next": "Assign Case" }, "Assign Case": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "Next": "Send Email" }, "Send Email": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "End": true } } }
    注意

    不用担心与 Lambda 资源值相关的错误。您会在本教程的后面部分中更新这些值。

  5. 选择下一步

  6. 在名称字段中,输入 SupportStateMachine

  7. 权限部分下,选择选择现有角色

  8. 选择 workflow-support(您创建的 IAM 角色)。

  9. 选择创建状态机。将出现一条消息,说明状态机已成功创建。

创建 Lambda 函数

使用 Lambda 运行时系统 API 创建 Lambda 函数。在此示例中,有三个工作流步骤,每个步骤对应于每个 Lambda 函数。

创建这些 Lambda 函数,如以下部分所述:

  • getId Lambda 函数 - 用作工作流的第一步,用于处理工单 ID 值。

  • addItem Lambda 类 - 用作工作流的第二步,将工单分配给员工并将数据存储在 DynamoDB 数据库中。

  • sendemail Lambda 类 - 用作工作流的第三步,使用 Amazon SES 向员工发送电子邮件以通知他们有关工单的信息。

getId Lambda 函数

创建一个 Lambda 函数,该函数返回的工单 ID 值将传递至工作流的第二步。

exports.handler = async (event) => { // Create a support case using the input as the case ID, then return a confirmation message try{ const myCaseID = event.inputCaseID; var myMessage = "Case " + myCaseID + ": opened..."; var result = { Case: myCaseID, Message: myMessage }; } catch(err){ console.log('Error', err); } };

在命令行中输入以下内容,以使用 webpack 将文件捆绑到名为 index.js 的文件中。

webpack getid.js --mode development --target node --devtool false --output-library-target umd -o index.js

然后将 index.js 压缩为一个名为 getid.js.zipZIP 文件。将此 ZIP 文件上传到您在此示例的主题中创建的 Amazon S3 存储桶。

GitHub 的此处提供了此代码示例。

addItem Lambda 类

创建一个 Lambda 函数,用于选择要分配工单的员工,然后将工单数据存储在名为 Case 的 DynamoDB 表中。

"use strict"; // Load the required clients and commands. const { PutItemCommand } = require ( "@aws-sdk/client-dynamodb" ); const { dynamoClient } = require ( "../libs/dynamoClient" ); exports.handler = async (event) => { try { // Helper function to send message using Amazon SNS. const val = event; //PersistCase adds an item to a DynamoDB table const tmp = Math.random() <= 0.5 ? 1 : 2; console.log(tmp); if (tmp == 1) { const params = { TableName: "Case", Item: { id: { N: val.Case }, empEmail: { S: "brmur@amazon.com" }, name: { S: "Tom Blue" }, }, }; console.log("adding item for tom"); try { const data = await dynamoClient.send(new PutItemCommand(params)); console.log(data); } catch (err) { console.error(err); } var result = { Email: params.Item.empEmail }; return result; } else { const params = { TableName: "Case", Item: { id: { N: val.Case }, empEmail: { S: "RECEIVER_EMAIL_ADDRESS" }, // Valid Amazon Simple Notification Services (Amazon SNS) email address. name: { S: "Sarah White" }, }, }; console.log("adding item for sarah"); try { const data = await dynamoClient.send(new PutItemCommand(params)); console.log(data); } catch (err) { console.error(err); } return params.Item.empEmail; var result = { Email: params.Item.empEmail }; } } catch (err) { console.log("Error", err); } };

在命令行中输入以下内容,以使用 webpack 将文件捆绑到名为 index.js 的文件中。

webpack additem.js --mode development --target node --devtool false --output-library-target umd -o index.js

然后将 index.js 压缩为一个名为 additem.js.zipZIP 文件。将此 ZIP 文件上传到您在此示例的主题中创建的 Amazon S3 存储桶。

GitHub 的此处提供了此代码示例。

sendemail Lambda 类

创建一个 Lambda 函数,用于向员工发送电子邮件以告知有关新工单的信息。将使用从第二步中传递的电子邮件地址。

// Load the required clients and commands. const { SendEmailCommand } = require ( "@aws-sdk/client-ses" ); const { sesClient } = require ( "../libs/sesClient" ); exports.handler = async (event) => { // Enter a sender email address. This address must be verified. const senderEmail = "SENDER_EMAIL" const sender = "Sender Name <" + senderEmail + ">"; // AWS Step Functions passes the employee's email to the event. // This address must be verified. const recepient = event.S; // The subject line for the email. const subject = "New case"; // The email body for recipients with non-HTML email clients. const body_text = "Hello,\r\n" + "Please check the database for new ticket assigned to you."; // The HTML body of the email. const body_html = `<html><head></head><body><h1>Hello!</h1><p>Please check the database for new ticket assigned to you.</p></body></html>`; // The character encoding for the email. const charset = "UTF-8"; var params = { Source: sender, Destination: { ToAddresses: [recepient], }, Message: { Subject: { Data: subject, Charset: charset, }, Body: { Text: { Data: body_text, Charset: charset, }, Html: { Data: body_html, Charset: charset, }, }, }, }; try { const data = await sesClient.send(new SendEmailCommand(params)); console.log(data); } catch (err) { console.error(err); } };

在命令行中输入以下内容,以使用 webpack 将文件捆绑到名为 index.js 的文件中。

webpack sendemail.js --mode development --target node --devtool false --output-library-target umd -o index.js

然后将 index.js 压缩为一个名为 sendemail.js.zipZIP 文件。将此 ZIP 文件上传到您在此示例的主题中创建的 Amazon S3 存储桶。

GitHub 的此处提供了此代码示例。

部署 Lambda 函数

部署 getid Lambda 函数:

  1. Amazon Web Services 控制台中打开 Lambda 控制台。

  2. 选择创建函数

  3. 选择从头开始创作

  4. 基本信息部分中,输入 getid 作为名称。

  5. 运行时系统中,选择 Node.js 14x

  6. 选择使用现有角色,然后选择 lambda-support(您在 中创建的 IAM 角色)。

  7. 选择创建函数

  8. 依次选择上传自 - Amazon S3 位置

  9. 选择上传,然后依次选择上传自 - Amazon S3 位置,再输入 Amazon S3 链接 URL

  10. 选择保存

  11. 对新的 Lambda 函数重复执行 additem.js.zipsendemail.js.zip 的过程。完成后,您将拥有三个 Lambda 函数,可以在 Amazon States Language 文档中引用这些函数。

将 Lambda 函数添加到工作流

  1. 打开 Lambda 控制台。请注意,您可以在右上角查看 Lambda Amazon 资源名称 (ARN) 值。

  2. 复制该值,然后将其粘贴到 Step Functions 控制台中的 Amazon States Language 文档的第 1 步中。

  3. 更新分配案例发送电子邮件步骤的资源。您可以通过这种方式将使用 Amazon SDK for Java 创建的 Lambda 函数连接到使用 Step Functions 创建的工作流中。

使用 Step Functions 控制台执行工作流

您可以在 Step Functions 控制台上调用工作流。执行会接收 JSON 输入。在此示例中,您可以将以下 JSON 数据传递到工作流。

{ "inputCaseID": "001" }

执行您的工作流:

  1. 在 Step Functions 控制台上,选择开始执行

  2. 输入部分中,传递 JSON 数据。查看工作流。每完成一个步骤后,它就会变为绿色。

  3. 如果步骤变为红色,则表示出现错误。您可以单击该步骤并查看可从右侧访问的日志。

    工作流完成后,您可以查看 DynamoDB 表中的数据。

删除 Amazon 资源

恭喜,您已经使用 Amazon SDK for Java 创建了一个 Amazon 无服务器工作流。如本教程开头所述,请务必在学习本教程时终止您创建的所有资源,以确保系统不会向您收费。您可以通过删除在本教程的创建 Amazon 资源 主题中创建的 Amazon CloudFormation 堆栈来实现此目的,方法如下所示:

  1. 打开 Amazon 管理控制台中的 Amazon CloudFormation

  2. 打开堆栈页面,然后选择堆栈。

  3. 选择删除