

 適用於 Java 的 AWS SDK 1.x 已於 2025 年 12 月 31 日end-of-support。我們建議您遷移至 [AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html)，以繼續接收新功能、可用性改善和安全性更新。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

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

做為活動或與其結合 Amazon SWF 使用的替代方案，您可以使用 [Lambda](https://aws.amazon.com/lambda/) 函數來代表工作流程中的工作單位，並以類似活動的方式進行排程。

本主題著重於如何使用 實作 Amazon SWF Lambda 任務 適用於 Java 的 AWS SDK。如需一般 Lambda 任務的詳細資訊，請參閱《 Amazon SWF 開發人員指南》中的[AWS Lambda 任務](https://docs.aws.amazon.com/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 您必須先設定 IAM 角色，以授予代表您執行 Lambda 函數的 Amazon SWF 許可，才能執行 Lambda 函數。如需如何執行此操作的完整資訊，請參閱[AWS Lambda 任務](https://docs.aws.amazon.com/amazonswf/latest/developerguide/lambda-task.html)。

當您註冊將使用 Lambda 任務的工作流程時，將需要此 IAM 角色的 Amazon Resource Name (ARN)。

## 建立 Lambda 函數
<a name="create-a-lambda-function"></a>

您可以使用多種不同的語言撰寫 Lambda 函數，包括 Java。如需如何撰寫、部署和使用 Lambda 函數的完整資訊，請參閱 [AWS Lambda 開發人員指南](https://docs.aws.amazon.com/lambda/latest/dg/)。

**注意**  
無論您使用哪種語言來撰寫 Lambda 函數，都可以排程和執行*任何* Amazon SWF 工作流程，無論您的工作流程程式碼是使用哪種語言撰寫。 會 Amazon SWF 處理執行函數和將資料傳出和傳出的詳細資訊。

以下是一個簡單的 Lambda 函數，可用於取代[建置簡單 Amazon SWF 應用程式](swf-hello.md)中的活動。
+ 此版本以 JavaScript 撰寫，可直接使用 輸入[AWS 管理主控台](https://console.aws.amazon.com/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，請參閱《 AWS Lambda 開發人員指南》中的[建立部署套件 (Java)](https://docs.aws.amazon.com/lambda/latest/dg/lambda-java-how-to-create-deployment-package.html)。您也想要查看標題為 [Java 中編寫 Lambda 函數程式設計模型的](https://docs.aws.amazon.com/lambda/latest/dg/java-programming-model.html)章節。

 Lambda 函數會將*事件*或*輸入*物件做為第一個參數，並將*內容*物件做為第二個參數，提供執行 Lambda 函數之請求的相關資訊。此特定函數預期輸入會以 JSON 表示，`who`欄位設定為用來建立問候語的名稱。

## 註冊工作流程以搭配 Lambda 使用
<a name="register-a-workflow-for-use-with-lam"></a>

若要讓工作流程排程 Lambda 函數，您必須提供 IAM 角色的名稱，該角色 Amazon SWF 提供叫用 Lambda 函數的許可。您可以使用 [RegisterWorkflowTypeRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RegisterWorkflowTypeRequest.html) 的 `withDefaultLambdaRole`或 `setDefaultLambdaRole`方法，在工作流程註冊期間設定此項目。

```
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 任務與排程活動類似。您可以使用 `ScheduleLambdaFunction`[DecisionType](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DecisionType.html) 和 [ScheduleLambdaFunctionDecisionAttributes](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/ScheduleLambdaFunctionDecisionAttributes.html) 提供[決策](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/Decision.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`，您必須提供*名稱*，也就是要呼叫的 Lambda 函數的 ARN，以及 *id*，這是 Amazon SWF 用來識別歷史記錄日誌中 Lambda 函數的名稱。

您也可以為 Lambda 函數提供選用*輸入*，並設定其*開始關閉逾時*值，這是允許 Lambda 函數在產生`LambdaFunctionTimedOut`事件之前執行的秒數。

**注意**  
此程式碼使用 [AWSLambdaClient](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/AWSLambdaClient.html) 來擷取 Lambda 函數的 ARN，並指定函數名稱。您可以使用此技術來避免在程式碼中硬式編碼完整的 ARN （包括您的 AWS 帳戶 ID)。

## 在決策者中處理 Lambda 函數事件
<a name="handle-lam-function-events-in-your-decider"></a>

 Lambda 任務將產生許多事件，您可以在工作流程工作者中輪詢決策任務時對其採取動作，對應於 Lambda 任務的生命週期，並使用 [EventType](https://docs.aws.amazon.com/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.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/HistoryEvent.html) `LambdaFunctionCompleted`[EventType](https://docs.aws.amazon.com/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.aws.amazon.com/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>

您可以在 *aws-java-developer-guide 儲存庫的 Github 上瀏覽此範例的完整來源 ：github：`<awsdocs/aws-java-developer-guide/tree/master/doc\_source/snippets/helloswf\_lambda/>*。 *aws-java-developer-guide* 