

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

# 使用 Step Functions 建立活動狀態機器
<a name="tutorial-creating-activity-state-machine"></a>

本教學課程會說明如何使用 Java 和 AWS Step Functions，建立以活動為基礎的狀態機器。活動可讓您控制從狀態機器其他位置執行的工作者程式碼。如需概觀，請參閱 [了解 Step Functions 中的狀態機器](concepts-statemachines.md) 中的 [了解 Step Functions 中的活動](concepts-activities.md)。

為了完成本教學，您需要以下項目：
+ [適用於 Java 的 開發套件](https://aws.amazon.com/sdk-for-java/)。本教學課程中的範例活動是使用 適用於 Java 的 AWS SDK 進行通訊的 Java 應用程式 AWS。
+ AWS 環境中或標準 AWS 組態檔案中的 憑證。如需詳細資訊，請參閱《 *適用於 Java 的 AWS SDK 開發人員指南*》中的[設定您的 AWS 登入](https://docs.aws.amazon.com/AWSSdkDocsJava/latest/DeveloperGuide/set-up-creds.html)資料。

## 步驟 1：建立活動
<a name="create-activity-state-machine-step-1"></a>

您必須讓 Step Functions 知道您想要建立其*工作者* （程式） *的活動*。Step Functions 會以建立活動身分的 Amazon Resource Name (ARN) 回應。使用此身分來協調狀態機器和工作者之間傳遞的資訊。

**重要**  
確保您的活動任務與您的狀態機器位於相同的 AWS 帳戶下。

1. 在 [Step Functions 主控台](https://console.aws.amazon.com/states/home)的左側導覽窗格中，選擇**活動**。

1. 選擇 **Create activity (建立活動)**。

1. 輸入活動**的名稱**，例如 `get-greeting`，然後選擇**建立活動**。

1. 建立活動任務時，請記下其 ARN，如以下範例所示。

   ```
   arn:aws:states:region:123456789012:activity:get-greeting
   ```

## 步驟 2：建立狀態機器
<a name="create-activity-state-machine-step-2"></a>

建立狀態機器以決定何時呼叫您的活動，以及您的工作者何時應執行其主要工作、收集並傳回結果。若要建立狀態機器，您將使用 Workflow Studio [程式碼編輯器](workflow-studio.md#wfs-interface-code-editor)的 。

1. 在 [Step Functions 主控台](https://console.aws.amazon.com/states/home)的左側導覽窗格中，選擇**狀態機器**。

1. 在**狀態機器**頁面上，選擇**建立狀態機器**。

1. 選擇**從空白建立**。

1. 為您的狀態機器命名，然後選擇**繼續**在 Workflow Studio 中編輯您的狀態機器。

1. 在本教學課程中，您將在程式碼編輯器中撰寫狀態機器的 [Amazon States Language](concepts-amazon-states-language.md)(ASL) 定義。若要這樣做，請選擇**程式碼**。

1. 移除現有的樣板程式碼並貼上下列程式碼。請記得將 `Resource` 欄位中的範例 ARN 取代為您先前在 中建立之活動任務的 ARN[步驟 1：建立活動](#create-activity-state-machine-step-1)。

   ```
   {
     "Comment": "An example using a Task state.",
     "StartAt": "getGreeting",
     "Version": "1.0",
     "TimeoutSeconds": 300,
     "States":
     {
       "getGreeting": {
         "Type": "Task",
         "Resource": "arn:aws:states:region:123456789012:activity:get-greeting",
         "End": true
       }
     }
   }
   ```

   這是使用 [Amazon States Language](concepts-amazon-states-language.md)(ASL) 的狀態機器描述。它定義名為 `getGreeting` 的單一 `Task` 狀態。如需詳細資訊，請參閱[狀態機器結構](statemachine-structure.md)。

1. 在 上[圖形視覺化](workflow-studio.md#wfs-interface-code-graph-viz)，確保您新增的 ASL 定義的工作流程圖表看起來與下列圖表類似。  
![\[以圖形顯示具有 RunActivity 任務狀態的狀態機器。\]](http://docs.aws.amazon.com/zh_tw/step-functions/latest/dg/images/tutorial-create-state-machine-custom-preview.png)

1. 為您的狀態機器指定名稱。若要這樣做，請選擇 **MyStateMachine** 預設狀態機器名稱旁的編輯圖示。然後，在**狀態機器組態**中，在**狀態機器名稱方塊中指定名稱**。

   針對本教學課程，輸入名稱 **ActivityStateMachine**。

1. （選用） 在**狀態機器組態**中，指定其他工作流程設定，例如狀態機器類型及其執行角色。

   在此教學課程中，請將所有預設選擇保留在**狀態機器設定**中。

   如果您[先前已建立具有狀態機器正確許可的 IAM 角色](procedure-create-iam-role.md)，並想要使用它，請在**許可**中，選取**選擇現有角色**，然後從清單中選擇角色。或選取**輸入角色 ARN**，然後為該 IAM 角色提供 ARN。

1. 在**確認角色建立**對話方塊中，選擇**確認**以繼續。

   您也可以選擇**檢視角色設定**以返回**狀態機器組態**。
**注意**  
如果您刪除 Step Functions 建立的 IAM 角色，Step Functions 稍後無法重新建立該角色。同樣地，如果您修改角色 （例如，從 IAM 政策中的主體移除 Step Functions)，Step Functions 稍後無法還原其原始設定。

## 步驟 3：實作工作者
<a name="create-activity-state-machine-step-3"></a>

建立*工作者*。工作者是一種程式，負責：
+ 使用 `GetActivityTask` API 動作輪詢活動的 Step Functions。
+ 使用您的程式碼執行活動工作 (例如，以下程式碼中的 `getGreeting()` 方法)。
+ 使用 `SendTaskSuccess`、`SendTaskFailure` 和 `SendTaskHeartbeat` API 動作傳回結果。

**注意**  
如需活動工作者的更完整範例，請參閱 [範例：Ruby 中的活動工作者](concepts-activities.md#example-ruby-activity-worker)。此範例根據最佳實務提供實作，可供您的活動工作者參考。此程式碼會實作可為輪詢器和活動工作者設定執行緒數量的消費者-生產者模式。

### 實作工作者
<a name="create-activity-state-machine-implement-worker"></a>

1. 建立名為 `GreeterActivities.java` 的檔案。

1. 新增以下程式碼至其中。

   ```
   import com.amazonaws.ClientConfiguration;
   import com.amazonaws.auth.EnvironmentVariableCredentialsProvider;
   import com.amazonaws.regions.Regions;
   import com.amazonaws.services.stepfunctions.AWSStepFunctions;
   import com.amazonaws.services.stepfunctions.AWSStepFunctionsClientBuilder;
   import com.amazonaws.services.stepfunctions.model.GetActivityTaskRequest;
   import com.amazonaws.services.stepfunctions.model.GetActivityTaskResult;
   import com.amazonaws.services.stepfunctions.model.SendTaskFailureRequest;
   import com.amazonaws.services.stepfunctions.model.SendTaskSuccessRequest;
   import com.amazonaws.util.json.Jackson;
   import com.fasterxml.jackson.databind.JsonNode;
   import java.util.concurrent.TimeUnit;
   
   
   public class GreeterActivities {
   
       public String getGreeting(String who) throws Exception {
           return "{\"Hello\": \"" + who + "\"}";
       }
   
       public static void main(final String[] args) throws Exception {
           GreeterActivities greeterActivities = new GreeterActivities();
           ClientConfiguration clientConfiguration = new ClientConfiguration();
           clientConfiguration.setSocketTimeout((int)TimeUnit.SECONDS.toMillis(70));
   
           AWSStepFunctions client = AWSStepFunctionsClientBuilder.standard()
                   .withRegion(Regions.US_EAST_1)
                   .withCredentials(new EnvironmentVariableCredentialsProvider())
                   .withClientConfiguration(clientConfiguration)
                   .build();
   
           while (true) {
               GetActivityTaskResult getActivityTaskResult =
                       client.getActivityTask(
                               new GetActivityTaskRequest().withActivityArn(ACTIVITY_ARN));
   
               if (getActivityTaskResult.getTaskToken() != null) {
                   try {
                       JsonNode json = Jackson.jsonNodeOf(getActivityTaskResult.getInput());
                       String greetingResult =
                               greeterActivities.getGreeting(json.get("who").textValue());
                       client.sendTaskSuccess(
                               new SendTaskSuccessRequest().withOutput(
                                       greetingResult).withTaskToken(getActivityTaskResult.getTaskToken()));
                   } catch (Exception e) {
                       client.sendTaskFailure(new SendTaskFailureRequest().withTaskToken(
                               getActivityTaskResult.getTaskToken()));
                   }
               } else {
                   Thread.sleep(1000);
               }
           }
       }
   }
   ```
**注意**  
此範例中的 `EnvironmentVariableCredentialsProvider` 類別假設已設定 `AWS_ACCESS_KEY_ID` (或 `AWS_ACCESS_KEY`) 和 `AWS_SECRET_KEY` (或 `AWS_SECRET_ACCESS_KEY`) 環境變數。如需提供必要登入資料給工廠的詳細資訊，請參閱*適用於 Java 的 AWS SDK 《 API 參考*》中的 [AWSCredentialsProvider](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/AWSCredentialsProvider.html)，以及《 *適用於 Java 的 AWS SDK 開發人員指南*》中的[設定登入 AWS 資料和開發區域](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html)。  
根據預設，軟體 AWS 開發套件最多會等待 50 秒，從伺服器接收任何操作的資料。此 `GetActivityTask` 操作是長時間輪詢操作，將等待最多 60 秒，以取得下一個可用任務。如要避免收到 `SocketTimeoutException` 錯誤，請將 SocketTimeout 設為 70 秒。

1. 在`GetActivityTaskRequest().withActivityArn()`建構函數的參數清單中，將`ACTIVITY_ARN`值取代為您先前在 中建立之活動任務的 ARN[步驟 1：建立活動](#create-activity-state-machine-step-1)。

## 步驟 4：執行狀態機器
<a name="create-activity-state-machine-step-4"></a>

當您開始執行狀態機器時，工作者會輪詢 Step Functions 以進行活動、執行其工作 （使用您提供的輸入），並傳回其結果。

1. 在 ***ActivityStateMachine*** 頁面上，選擇 **Start execution (開始執行)**。

   隨即顯示**開始執行**對話方塊。

1. 在**開始執行**對話方塊中，執行下列動作：

   1. （選用） 輸入自訂執行名稱以覆寫產生的預設值。
**非 ASCII 名稱和記錄**  
Step Functions 接受包含非 ASCII 字元的狀態機器、執行、活動和標籤名稱。由於這類字元會阻止 Amazon CloudWatch 記錄資料，因此我們建議您僅使用 ASCII 字元，以便您可以追蹤 Step Functions 指標。

   1. 在**輸入**方塊中，輸入下列 JSON 輸入來執行您的工作流程。

      ```
      {
        "who": "AWS Step Functions"
      }
      ```

   1. 選擇 **Start execution (開始執行)**。

   1. Step Functions 主控台會將您導向至標題為執行 ID 的頁面。此頁面稱為*執行詳細資訊*頁面。在此頁面上，您可以在執行進行時或完成後檢閱執行結果。

      若要檢閱執行結果，請在**圖形檢視**中選擇個別狀態，然後選擇[步驟詳細資訊](concepts-view-execution-details.md#exec-details-intf-step-details)窗格上的個別索引標籤，分別檢視每個狀態的詳細資訊，包括輸入、輸出和定義。如需您可以在執行詳細資訊頁面上檢視之*執行資訊的詳細資訊*，請參閱 [執行詳細資訊概觀](concepts-view-execution-details.md#exec-details-interface-overview)。

## 步驟 5：執行和停用工作者
<a name="create-activity-state-machine-step-5"></a>

若要讓工作者輪詢您的活動狀態機器，您必須執行工作者。

1. 在命令列上，導覽至您建立 `GreeterActivities.java` 的目錄。

1. 若要使用 AWS SDK，請將 `lib`和 `third-party` 目錄的完整路徑新增至建置檔案和 Java 的相依性`CLASSPATH`。如需詳細資訊，請參閱[《 開發人員指南》中的下載和擷取 SDK](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-install.html#download-and-extract-sdk)。 *適用於 Java 的 AWS SDK *

1. 編譯檔案。

   ```
   $ javac GreeterActivities.java
   ```

1. 執行 檔案。

   ```
   $ java GreeterActivities
   ```

1. 在 [Step Functions 主控台](https://console.aws.amazon.com/states/home?region=us-east-1#/)上，導覽至*執行詳細資訊*頁面。

1. 執行完成時，請檢查執行的結果。

1. 停用工作者。