

 适用于 Java 的 Amazon SDK 1.x于2025年 end-of-support 12月31日达到。我们建议您迁移到 [Amazon SDK for Java 2.x](https://docs.amazonaws.cn/sdk-for-java/latest/developer-guide/home.html) 以继续获得新功能、可用性改进和安全更新。

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

# Lambda 任务
<a name="swf-lambda-task"></a>

另一个方法是与 Amazon SWF 活动一起使用，就是使用 [Lambda](https://www.amazonaws.cn/lambda/) 函数代表工作流中的工作单元，并按照安排活动的相似方法安排它们。

本主题主要介绍如何使用适用于 Java 的 Amazon SDK 实施 Amazon SWF Lambda 任务。有关 Lambda 任务的更多一般性信息，请参阅《Amazon SWF Developer Guide》中的 [Amazon Lambda Tasks](https://docs.amazonaws.cn/amazonswf/latest/developerguide/lambda-task.html)。

## 设置跨服务 IAM 角色以运行 Lambda 函数
<a name="set-up-a-cross-service-iam-role-to-run-your-lambda-function"></a>

在 Amazon SWF 能够运行您的 Lambda 函数前，需要设置一个 IAM 角色，授予让它代表您运行 Lambda 函数的 Amazon SWF 权限。有关如何完成该操作的完整信息，请参阅 [Amazon Lambda Tasks](https://docs.amazonaws.cn/amazonswf/latest/developerguide/lambda-task.html)。

在注册将使用 Lambda 任务的工作流时，将需要此 IAM 角色的 Amazon 资源名称 (ARN)。

## 创建 Lambda 函数
<a name="create-a-lambda-function"></a>

您可以使用包括 Java 在内的多种不同语言编写 Lambda 函数。有关如何编写、部署和使用 Lambda 函数的完整信息，请参阅《[Amazon Lambda 开发人员指南](https://docs.amazonaws.cn/lambda/latest/dg/)》。

**注意**  
使用哪种语言编写 Lambda 函数并不重要，无论使用哪种语言编写工作流代码，*所有* Amazon SWF 工作流都可以安排和运行您的函数。Amazon SWF 处理运行函数和传入传出数据的详细信息。

下面是一个简单的 Lambda 函数，它可以用于代替[构建简单 Amazon SWF 应用程序](swf-hello.md)中的活动。
+ 该版本使用 JavaScript 编写，使用 [Amazon Web Services 管理控制台](https://console.amazonaws.cn/console/home)可以直接输入。

  ```
  exports.handler = function(event, context) {
      context.succeed("Hello, " + event.who + "!");
  };
  ```
+ 以下是使用 Java 编写的相同函数，您同样可以在 Lambda 上部署和运行它：

  ```
  package example.swf.hellolambda;
  
  import com.amazonaws.services.lambda.runtime.Context;
  import com.amazonaws.services.lambda.runtime.RequestHandler;
  import com.amazonaws.util.json.JSONException;
  import com.amazonaws.util.json.JSONObject;
  
  public class SwfHelloLambdaFunction implements RequestHandler<Object, Object> {
      @Override
      public Object handleRequest(Object input, Context context) {
          String who = "{SWF}";
          if (input != null) {
              JSONObject jso = null;
              try {
                  jso = new JSONObject(input.toString());
                  who = jso.getString("who");
              } catch (JSONException e) {
                  e.printStackTrace();
              }
          }
          return ("Hello, " + who + "!");
      }
  }
  ```
**注意**  
要了解有关将 Java 函数部署到 Lambda 的更多信息，请参阅《Amazon Lambda 开发人员指南》中的[创建部署包 (Java)](https://docs.amazonaws.cn/lambda/latest/dg/lambda-java-how-to-create-deployment-package.html)。您可能还希望查看标题为[使用 Java 编写 Lambda 函数的编程模型](https://docs.amazonaws.cn/lambda/latest/dg/java-programming-model.html)的章节。

 Lambda 函数使用 *event* 或 *input* 对象作为第一个参数，使用 *context* 对象作为第二个参数，提供有关运行 Lambda 函数的请求的相关信息。该特定函数要求使用 JSON 提供输入，并将 `who` 字段设置为用于创建问候语的名称。

## 注册用于 Lambda 的工作流
<a name="register-a-workflow-for-use-with-lam"></a>

对于预定 Lambda 函数的工作流，必须提供 IAM 角色的名称，由其为 Amazon SWF 提供调用 Lambda 函数的权限。您可以在工作流注册期间，使用 `withDefaultLambdaRole`RegisterWorkflowTypeRequest`setDefaultLambdaRole` 的 [ 或 ](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RegisterWorkflowTypeRequest.html) 方法完成该设置。

```
System.out.println("** Registering the workflow type '" + WORKFLOW + "-" + WORKFLOW_VERSION
        + "'.");
try {
    swf.registerWorkflowType(new RegisterWorkflowTypeRequest()
        .withDomain(DOMAIN)
        .withName(WORKFLOW)
        .withDefaultLambdaRole(lambda_role_arn)
        .withVersion(WORKFLOW_VERSION)
        .withDefaultChildPolicy(ChildPolicy.TERMINATE)
        .withDefaultTaskList(new TaskList().withName(TASKLIST))
        .withDefaultTaskStartToCloseTimeout("30"));
}
catch (TypeAlreadyExistsException e) {
```

## 调度 Lambda 任务
<a name="schedule-a-lam-task"></a>

调度 Lambda 任务与调度活动相似。您提供一条[决策](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/Decision.html)，该决策具有“ScheduleLambdaFunction”[DecisionType](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DecisionType.html) 和 [ScheduleLambdaFunctionDecisionAttributes](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/ScheduleLambdaFunctionDecisionAttributes.html)。

```
running_functions == 0 && scheduled_functions == 0) {
AWSLambda lam = AWSLambdaClientBuilder.defaultClient();
GetFunctionConfigurationResult function_config =
    lam.getFunctionConfiguration(
            new GetFunctionConfigurationRequest()
                .withFunctionName("HelloFunction"));
String function_arn = function_config.getFunctionArn();

ScheduleLambdaFunctionDecisionAttributes attrs =
    new ScheduleLambdaFunctionDecisionAttributes()
        .withId("HelloFunction (Lambda task example)")
        .withName(function_arn)
        .withInput(workflow_input);

decisions.add(
```

在 `ScheduleLambdaFuntionDecisionAttributes` 中，必须提供 *name*，这是要调用的 Lambda 函数的 ARN；还必须提供 *id*，这是 Amazon SWF 用于在历史记录日志中标识 Lambda 函数的名称。

还可以为 Lambda 函数提供可选的 *input* 并设置其 *start to close timeout* 值，这是在生成 `LambdaFunctionTimedOut` 事件之前允许 Lambda 函数运行的秒数。

**注意**  
在给出函数名称后，该代码使用 [AWSLambdaClient](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/lambda/AWSLambdaClient.html) 检索 Lambda 函数的 ARN。您可以使用该方法，以避免您的代码中包含完整 ARN 的硬编码（包括 Amazon Web Services 账户 ID）。

## 在决策程序中处理 Lambda 函数事件
<a name="handle-lam-function-events-in-your-decider"></a>

 Lambda 任务会使用 LambdaEventType[ 值 (如 ](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/EventType.html)、`LambdaFunctionScheduled` 和 `LambdaFunctionStarted`) 生成与 `LambdaFunctionCompleted` 任务生命周期对应的多个事件，在工作流工作线程中轮询决策任务时可以对这些事件执行操作。如果 Lambda 函数失败或运行时间超出其超时值，您会分别收到 `LambdaFunctionFailed` 或 `LambdaFunctionTimedOut` 事件类型。

```
boolean function_completed = false;
String result = null;

System.out.println("Executing the decision task for the history events: [");
for (HistoryEvent event : events) {
    System.out.println("  " + event);
    EventType event_type = EventType.fromValue(event.getEventType());
    switch(event_type) {
    case WorkflowExecutionStarted:
        workflow_input =
            event.getWorkflowExecutionStartedEventAttributes()
                 .getInput();
        break;
    case LambdaFunctionScheduled:
        scheduled_functions++;
        break;
    case ScheduleLambdaFunctionFailed:
        scheduled_functions--;
        break;
    case LambdaFunctionStarted:
        scheduled_functions--;
        running_functions++;
        break;
    case LambdaFunctionCompleted:
        running_functions--;
        function_completed = true;
        result = event.getLambdaFunctionCompletedEventAttributes()
                      .getResult();
        break;
    case LambdaFunctionFailed:
        running_functions--;
        break;
    case LambdaFunctionTimedOut:
        running_functions--;
        break;
```

## 从您的 Lambda 函数接收输出
<a name="receive-output-from-your-lam-function"></a>

在 [HistoryEvent](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/HistoryEvent.html) 上接收 `LambdaFunctionCompleted`[EventType](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/EventType.html), you can retrieve your 0 function’s return value by first calling `getLambdaFunctionCompletedEventAttributes` 时，以获取 [LambdaFunctionCompletedEventAttributes](https://docs.amazonaws.cn/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/LambdaFunctionCompletedEventAttributes.html) 对象，然后调用其 `getResult` 方法以检索 Lambda 函数的输出：

```
 LambdaFunctionCompleted:
running_functions--;
```

## 此示例的完整源代码
<a name="complete-source-for-this-example"></a>

您可以在 Github 上的 *aws-java-developer-guide* 存储库中，浏览 *complete source :github:`<awsdocs/aws-java-developer-guide/tree/master/doc\$1source/snippets/helloswf\$1lambda/>*，以查看此示例。