

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# HelloWorldWorkflow アプリケーション
<a name="getting-started-example-helloworldworkflow"></a>

基本的な [HelloWorld](getting-started-example-helloworld.md) 例は、ワークフローのように構成されていますが、Amazon SWF ワークフローとはいくつかの重要な点で異なります。


**従来のアプリケーションと Amazon SWF ワークフローアプリケーション**  

| HelloWorld | Amazon SWF ワークフロー | 
| --- | --- | 
| 単一のプロセスとしてローカルで実行されます。 | 複数のプロセスとして複数のシステム (Amazon EC2 インスタンス、プライベートデータセンター、クライアントコンピュータなど) に分散して実行できます。各プロセスで同じオペレーティングシステムを実行する必要もありません。 | 
| アクティビティは同期メソッドであり、完了するまで他はブロックされます。 | アクティビティは非同期メソッドとして即座に戻り、完了するまで待つ間にワークフローで他のタスクを実行できます。 | 
| ワークフローワーカーは、アクティビティワーカーとやり取りするために、適切なメソッドを呼び出します。 | ワークフローワーカーは、仲介として動作する Amazon SWF で HTTP リクエストを使用して、アクティビティワーカーとやり取りします。 | 
| ワークフロースターターは、ワークフローワーカーとやり取りするために、適切なメソッドを呼び出します。 | ワークフロースターターは、仲介として動作する Amazon SWF で HTTP リクエストを使用して、ワークフローワーカーとやり取りします。 | 

分散非同期ワークフローアプリケーションは、ワークフローワーカーとアクティビティワーカーのやり取りに直接ウェブサービスの呼び出しを使用することで、ゼロから実装することもできます。ただし、その場合は、複数のアクティビティの非同期実行を管理したり、データフローを処理したりするために必要なすべての複雑なコードを実装する必要があります。 AWS Flow Framework for Java と Amazon SWF はこれらの詳細をすべて処理するため、ビジネスロジックの実装に集中できます。

HelloWorldWorkflow は、HelloWorld の修正バージョンであり、Amazon SWF ワークフローとして実行されます。次の図は、2 つのアプリケーションの大まかな仕組みを示しています。

![\[従来バージョンと Amazon SWF バージョンの Hello World!\]](http://docs.aws.amazon.com/ja_jp/amazonswf/latest/awsflowguide/images/workflow_conceptual_welcome.png)


HelloWorld は単一のプロセスとして実行されます。スターター、ワークフローワーカー、およびアクティビティワーカーのやり取りには、従来のメソッド呼び出しが使用されます。`HelloWorldWorkflow`では、スターター、ワークフローワーカー、およびアクティビティワーカーは、HTTP リクエストを使用して Amazon SWF を介して相互作用する分散コンポーネントです。Amazon SWF は、ワークフローおよびアクティビティタスクのリストを維持することで相互作用を管理し、それぞれのコンポーネントにディスパッチします。このセクションでは、HelloWorldWorkflow を使用して、このフレームワークの仕組みを説明します。

HelloWorldWorkflow は AWS Flow Framework for Java API を使用して実装されます。この API は、バックグラウンドで Amazon SWF とやり取りする際の複雑な詳細を処理し、開発プロセスを大幅に簡素化します。Java アプリケーション用に設定されている HelloWorld AWS Flow Framework と同じプロジェクトを使用できます。ただし、アプリケーションを実行するには、Amazon SWF アカウントを以下のように設定する必要があります。
+  AWS アカウントをお持ちでない場合は、[Amazon Web Services](https://aws.amazon.com/) でサインアップします。
+ アカウントのアクセス ID とシークレットキー ID を、AWS\$1ACCESS\$1KEY\$1ID 環境変数と AWS\$1SECRET\$1KEY 環境変数にそれぞれ割り当てます。コードのリテラルキー値は公開しないようお勧めします。環境変数に保存すると、問題に対処しやすくなります。
+ [Amazon Simple Workflow Service](https://aws.amazon.com/swf/) で、Amazon SWF アカウントにサインアップします。
+ にログイン AWS マネジメントコンソール し、Amazon SWF サービスを選択します。
+ 右上隅の **[ドメインの管理]** を選択し、新しい Amazon SWF ドメインを登録します。*ドメイン*は、アプリケーションリソース (ワークフロータイプ、アクティビティタイプ、ワークフロー実行など) の論理コンテナです。ドメイン名は任意に指定できます。このウォークスルーでは「helloWorldWalkthrough」を使用します。

HelloWorldWorkflow を実装するには、helloWorld.HelloWorld パッケージのコピーをプロジェクトディレクトリに作成し、名前を helloWorld.HelloWorldWorkflow とします。以下のセクションでは、元の HelloWorld コードを変更して AWS Flow Framework for Java を使用し、Amazon SWF ワークフローアプリケーションとして実行する方法について説明します。

## HelloWorldWorkflow アクティビティワーカー
<a name="getting-started-example-helloworldworkflow.activities"></a>

HelloWorld では、アクティビティワーカーを単一のクラスとして実装しました。 AWS Flow Framework for Java アクティビティワーカーには 3 つの基本コンポーネントがあります。
+ *アクティビティメソッド* — 実際のタスクを実行するこのメソッドは、インターフェイスで定義され、関連するクラスに実装されます。
+ [ActivityWorker](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/ActivityWorker.html) クラスは、アクティビティメソッドと Amazon SWF 間のやり取りを管理します。
+ *アクティビティホスト*アプリケーションは、アクティビティワーカーを登録して開始し、クリーンアップを処理します。

このセクションでは、アクティビティメソッドについて説明します。他の 2 つのクラスについては後で説明します。

HelloWorldWorkflow は、アクティビティインターフェイスを `GreeterActivities` で次のように定義します。

```
import com.amazonaws.services.simpleworkflow.flow.annotations.Activities;
import com.amazonaws.services.simpleworkflow.flow.annotations.ActivityRegistrationOptions;

@ActivityRegistrationOptions(defaultTaskScheduleToStartTimeoutSeconds = 300,
                             defaultTaskStartToCloseTimeoutSeconds = 10)
@Activities(version="1.0")

public interface GreeterActivities {
   public String getName();
   public String getGreeting(String name);
   public void say(String what);
}
```

このインターフェイスは HelloWorld に厳密に必要なものではありませんが、 AWS Flow Framework for Java アプリケーション用です。インターフェイスの定義自体は変わっていないことに注意してください。ただし、Java 注釈 AWS Flow Framework には 2 つの [@ActivityRegistrationOptions](annotations.md#annotations-activityregistration)と [@Activities](annotations.md#annotations-activities)をインターフェイス定義に適用する必要があります。注釈は設定情報を提供し、 AWS Flow Framework for Java 注釈プロセッサにインターフェイス定義を使用して*アクティビティクライアント*クラスを生成するように指示します。これについては、後で説明します。

`@ActivityRegistrationOptions` には、いくつかの名前付きの値があり、アクティビティの動作を設定するために使用されます。HelloWorldWorkflow では 2 つのタイムアウトを指定します。
+ `defaultTaskScheduleToStartTimeoutSeconds` は、アクティビティのタスクリストでタスクをキューイングできる時間を指定します。300 秒 (5 分) に設定されています。
+ `defaultTaskStartToCloseTimeoutSeconds` は、アクティビティでタスクを実行する最大許容時間を指定します。10 秒に設定されています。

これらのタイムアウトにより、適切な時間内にアクティビティでタスクが完了されます。どちらかのタイムアウトを超えると、フレームワークでエラーが生成されます。ワークフローワーカーはエラーの処理方法を決定する必要があります。このようなエラーの処理方法については、「[エラー処理](errorhandling.md)」を参照してください。

`@Activities` には複数の値がありますが、通常はアクティビティのバージョン番号を指定するだけです。このバージョン番号により、世代が異なるアクティビティ実装を追跡できます。アクティビティインターフェイスを Amazon SWF に登録した後で変更した場合 (`@ActivityRegistrationOptions` の値を変更するなど) は、新しいバージョン番号を使用する必要があります。

HelloWorldWorkflow では、次のようにアクティビティメソッドを `GreeterActivitiesImpl` に実装します。

```
public class GreeterActivitiesImpl implements GreeterActivities {
   @Override
   public String getName() {
      return "World";
   }
   @Override
   public String getGreeting(String name) {
      return "Hello " + name;
   }
   @Override
   public void say(String what) {
      System.out.println(what);
   }
}
```

このコードは HelloWorld の実装と同じであることに注意してください。アクティビティの中核となるの AWS Flow Framework は、一部のコードを実行して結果を返すメソッドにすぎません。標準的なアプリケーションと Amazon SWF ワークフローアプリケーションの違いは、ワークフローでアクティビティを実行する方法、アクティビティの実行場所、および結果をワークフローワーカーに返す方法にあります。

## HelloWorldWorkflow ワークフローワーカー
<a name="getting-started-example-helloworldworkflow.workflow"></a>

Amazon SWF ワークフローワーカーには 3 つの基本コンポーネントがあります。
+ *ワークフロー実装*は、ワークフロー関連のタスクを実行するクラスです。
+ *アクティビティクライアント*クラスは、基本的にアクティビティクラスのプロキシであり、アクティビティメソッドを非同期的に実行するためにワークフロー実装で使用されます。
+ [WorkflowWorker](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/WorkflowWorker.html) クラスは、ワークフローと Amazon SWF のやり取りを管理します。

このセクションでは、ワークフロー実装とアクティビティクライアントについて説明します。`WorkflowWorker`クラスについては後で説明します。

HelloWorldWorkflow では、次のようにワークフローインターフェイスを `GreeterWorkflow` で定義します。

```
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;

@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 3600)
public interface GreeterWorkflow {
   @Execute(version = "1.0")
   public void greet();
}
```

このインターフェイスは、HelloWorld に厳密に必要なわけではありませんが、 AWS Flow Framework for Java アプリケーションに不可欠です。ワークフローインターフェイス定義[@WorkflowRegistrationOptions](annotations.md#annotations-workflowregistrationoptions)には、Java 注釈 AWS Flow Framework に 2 つの [@Workflow](annotations.md#annotations-workflow)と を適用する必要があります。注釈は設定情報を提供し、後で説明するように、 AWS Flow Framework for Java 注釈プロセッサがインターフェイスに基づいてワークフロークライアントクラスを生成するように指示します。

`@Workflow` には、デフォルト値である *dataConverter* でよく使用される dataConverter というオプションのパラメータが 1 つあります。これは、JsonDataConverter を使用する必要があることを示します。 NullDataConverter

`@WorkflowRegistrationOptions` にも複数のオプションのパラメータがあります。これらは、ワークフローワーカーの設定に使用できます。ここでは、`defaultExecutionStartToCloseTimeoutSeconds` を設定し、ワークフローの実行時間を指定します。最大は 3600 秒 (1 時間) です。

`GreeterWorkflow` インターフェイス定義は、HelloWorld とは 1 つの重要な点 ([@Execute](annotations.md#annotations-execute) 注釈) で異なります。ワークフローインターフェイスで指定するメソッドは、アプリケーション (ワークフロースターターなど) から呼び出すことができます。これらのメソッドの数は限られており、メソッドごとにロールが異なります。フレームワークはワークフローインターフェイスメソッドの名前やパラメータリストを指定しません。ユーザーがワークフローに適した名前やパラメータリストを使用し、 AWS Flow Framework for Java の注釈を適用してメソッドのロールを特定します。

`@Execute` には 2 つの目的があります。
+ ワークフローのエントリポイントとして `greet` を識別します。これは、ワークフローを開始するために、ワークフロースターターで呼び出すメソッドです。通常、エントリポイントには 1 つ以上のパラメータを設定できます。これにより、スターターはワークフローを初期化できます。ただし、この例では初期化が不要です。
+ ワークフローのバージョン番号を指定します。これにより、世代が異なるワークフロー実装を追跡できます。ワークフローインターフェイスを Amazon SWF に登録した後で変更する (タイムアウト値を変更するなど) には、新しいバージョン番号を使用する必要があります。

ワークフローインターフェイスに設定できる他のメソッドについては、「[ワークフローコントラクトとアクティビティコントラクト](features.workflow.md)」を参照してください。

HelloWorldWorkflow では、次のようにワークフローを `GreeterWorkflowImpl` に実装します。

```
import com.amazonaws.services.simpleworkflow.flow.core.Promise;

public class GreeterWorkflowImpl implements GreeterWorkflow {
   private GreeterActivitiesClient operations = new GreeterActivitiesClientImpl();

   public void greet() {
     Promise<String> name = operations.getName();
     Promise<String> greeting = operations.getGreeting(name);
     operations.say(greeting);
   }
}
```

このコードは HelloWorld に似ていますが、2 つの重要な相違点があります。
+ `GreeterWorkflowImpl` は、`GreeterActivitiesImpl` の代わりにアクティビティクライアントとして `GreeterActivitiesClientImpl` のインスタンスを作成し、クライアントオブジェクトのメソッドを呼び出してアクティビティを実行します。
+ 名前とグリーティングアクティビティは、`String` オブジェクトの代わりに `Promise<String>` オブジェクトを返します。

HelloWorld は単一のプロセスとしてローカルで実行される標準の Java アプリケーションです。そのため、`GreeterWorkflowImpl` でワークフロートポロジーを実装するには、単に `GreeterActivitiesImpl` のインスタンスを作成し、メソッドを順に呼び出して、戻り値をアクティビティ間で受け渡すだけです。Amazon SWF ワークフローの場合も同様に、アクティビティのタスクは `GreeterActivitiesImpl` のアクティビティメソッドで実行されます。ただし、このメソッドはワークフローと同じプロセスで実行されない場合があります。同じシステムで実行されない場合さえあります。したがって、ワークフローではアクティビティを非同期的に実行する必要があります。以上の要件に伴って以下の問題が生じします。
+ 異なるプロセス (異なるシステムの場合もある) で実行されている可能性があるアクティビティメソッドを実行する方法。
+ アクティビティメソッドを非同期的に実行する方法。
+ アクティビティの入力と戻り値を管理する方法。たとえば、アクティビティ A の戻り値がアクティビティ B への入力である場合、アクティビティ A が完了するまでアクティビティ B の実行をブロックする必要があります。

使い慣れた Java フロー制御、アクティビティクライアント、および `Promise<T>` を組み合わせることで、さまざまなワークフロートポロジーをアプリケーションの制御フローで実装できます。

### アクティビティクライアント
<a name="getting-started-example-helloworldworkflow.workflow.client"></a>

`GreeterActivitiesClientImpl` は、基本的に `GreeterActivitiesImpl` のプロキシであり、ワークフロー実装で `GreeterActivitiesImpl` のメソッドを非同期的に実行できます。

`GreeterActivitiesClient` クラスと `GreeterActivitiesClientImpl` クラスは自動生成されます。この自動生成には、`GreeterActivities` クラスに適用した注釈で提供される情報が使用されます。これらをユーザーが実装する必要はありません。

**注記**  
プロジェクトを保存すると、これらのクラスが Eclipse で生成されます。生成されたコードは、プロジェクトディレクトリの `.apt_generated` サブディレクトリで確認できます。  
`GreeterWorkflowImpl` クラスでのコンパイルエラーを回避するには、`.apt_generated` ディレクトリを **[Java Build Path]** (Java ビルドパス) ダイアログボックスの **[Order and Export]** (オーダーとエクスポート) タブの一番上に移動することをお勧めします。

ワークフローワーカーは、対応するクライアントメソッドを呼び出すことで、アクティビティを実行します。このメソッドは非同期であり、`Promise<T>` オブジェクトを即座に返します。ここで `T` はアクティビティの戻り値の型です。返される `Promise<T>` オブジェクトは、基本的に、アクティビティメソッドから最終的に返される値のプレースホルダです。
+ アクティビティクライアントメソッドが戻った最初の時点では、`Promise<T>` オブジェクトは*準備ができていない状態*です。この状態は、オブジェクトがまだ有効な戻り値を反映していないことを示します。
+ 次に対応するアクティビティメソッドがタスクを完了して戻ると、フレームワークは `Promise<T>` オブジェクトに戻り値を割り当て、これを *準備完了状態*にします。

### プロミス <T>Type
<a name="getting-started-example-helloworldworkflow.workflow.promise"></a>

`Promise<T>` の主目的は、非同期コンポーネント間のデータフローを管理し、これらのコンポーネントの実行時期を制御することです。これにより、アプリケーションでは、明示的に同期を管理したり、タイマーなどの機構に依存したりしなくても、非同期コンポーネントが予定より早く実行するのをブロックできます。アクティビティクライアントメソッドを呼び出すと、このメソッドは即座に戻ります。ただし、フレームワークでは入力の `Promise<T>` オブジェクトが準備完了して有効なデータを反映するまで、対応するアクティビティメソッドの実行を遅らせます。

`GreeterWorkflowImpl` の観点からは、3 つすべてのアクティビティクライアントメソッドが即座に戻ります。`GreeterActivitiesImpl` の観点からは、フレームワークは `name` が完了するまで `getGreeting` を呼び出さず、`getGreeting` が完了するまで `say` を呼び出しません。

`HelloWorldWorkflow` では `Promise<T>` を使用してアクティビティ間でデータを受け渡すことで、アクティビティメソッドで無効なデータが使用されないようにします。さらに、アクティビティの実行時期を制御し、ワークフロートポロジーを暗黙で定義します。各アクティビティの `Promise<T>` の戻り値を次のアクティビティに渡すには、アクティビティを順に実行するためのリニアトポロジー (前述) を定義する必要があります。 AWS Flow Framework for Java では、特別なモデリングコードを使用して、標準の Java フロー制御と だけでなく、複雑なトポロジーも定義する必要はありません`Promise<T>`。シンプルなパラレルトポロジーの実装方法を示す例については、「[HelloWorldWorkflowParallel アクティビティワーカー](getting-started-example-helloworldworkflowparallel.md#getting-started-example-helloworldworkflowparallel.activities)」を参照してください。

**注記**  
アクティビティメソッド (`say` など) が値を返さない場合は、対応するクライアントメソッドから `Promise<Void>` オブジェクトが返されます。オブジェクトをデータを反映しませんが、最初は準備未完了状態で、アクティビティが完了すると準備完了状態になります。したがって、`Promise<Void>` オブジェクトを他のアクティビティクライアントメソッドに渡し、元のアクティビティが完了するまで実行を遅らせることができます。

`Promise<T>` を使用すると、ワークフロー実装ではアクティビティクライアントメソッドとその戻り値を同期メソッドのように使用できます。ただし、`Promise<T>` オブジェクトの値にアクセスする場合は注意が必要です。Java の [Future<T>](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html) タイプとは異なり、フレームワークで処理するのは `Promise<T>` の同期であり、アプリケーションではありません。`Promise<T>.get` を呼び出したときに、オブジェクトが準備未完了であれば、`get` から例外がスローされます。`HelloWorldWorkflow` が `Promise<T>` オブジェクトに直接アクセスすることはありません。オブジェクトをアクティビティ間で受け渡すだけです。オブジェクトが準備完了状態になると、フレームワークでは値を抽出し、その値を標準タイプとしてアクティビティメソッドに渡します。

`Promise<T>` オブジェクトは、必ず非同期コードでアクセスする必要があります。ここで、フレームワークは、オブジェクトを準備状態にし、有効な値を表します。`HelloWorldWorkflow` は、`Promise<T>` オブジェクトをアクティビティのクライアントメソッドにのみ渡して、問題を解決します。ワークフロー実装で `Promise<T>` オブジェクトの値にアクセスするには、オブジェクトを *非同期ワークフローメソッド*に渡します。このメソッドはアクティビティのように動作します。例については、[HelloWorldWorkflowAsync アプリケーション](getting-started-example-helloworldworkflowasync.md)を参照してください。

## HelloWorldWorkflow のワークフロー実装とアクティビティ実装
<a name="getting-started-example-helloworldworkflow.host"></a>

ワークフロー実装とアクティビティ実装には、ワーカークラスとして [ActivityWorker](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/ActivityWorker.html) と [WorkflowWorker](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/WorkflowWorker.html) に関連付けられています。これらのワーカークラスでは、Amazon SWF とアクティビティ/ワークフロー実装の間の通信を処理するために、適切な Amazon SWF タスクリストでタスクをポーリングし、各タスクの適切なメソッドを実行して、データフローを管理します。詳細については、「[AWS Flow Framework 基本的な概念: アプリケーション構造](awsflow-basics-application-structure.md)」を参照してください。

アクティビティ/ワーカー実装と対応するワーカーオブジェクトを関連付けるには、以下の操作を行うワーカーアプリケーションを 1 つ以上実装します。
+ ワークフローまたはアクティビティを Amazon SWF に登録する。
+ ワーカーオブジェクトを作成してワークフローまたはアクティビティのワーカー実装に関連付ける。
+ Amazon SWF との通信を開始するようワーカーオブジェクトに指示する。

ワークフローとアクティビティを別個のプロセスとして実行する場合は、ワークフローとアクティビティのワーカーホストを別個に実装する必要があります。例については、[HelloWorldWorkflowDistributed アプリケーション](getting-started-example-helloworldworkflowdistributed.md)を参照してください。シンプルにするために、HelloWorldWorkflow では以下のように 1 つのワーカーホストを実装し、アクティビティとワークフローのワーカーを同じプロセスで実行します。

```
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient;
import com.amazonaws.services.simpleworkflow.flow.ActivityWorker;
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;

public class GreeterWorker  {
   public static void main(String[] args) throws Exception {
     ClientConfiguration config = new ClientConfiguration().withSocketTimeout(70*1000);

     String swfAccessId = System.getenv("AWS_ACCESS_KEY_ID");
     String swfSecretKey = System.getenv("AWS_SECRET_KEY");
     AWSCredentials awsCredentials = new BasicAWSCredentials(swfAccessId, swfSecretKey);

     AmazonSimpleWorkflow service = new AmazonSimpleWorkflowClient(awsCredentials, config);
     service.setEndpoint("https://swf.us-east-1.amazonaws.com");

     String domain = "helloWorldWalkthrough";
     String taskListToPoll = "HelloWorldList";

     ActivityWorker aw = new ActivityWorker(service, domain, taskListToPoll);
     aw.addActivitiesImplementation(new GreeterActivitiesImpl());
     aw.start();

     WorkflowWorker wfw = new WorkflowWorker(service, domain, taskListToPoll);
     wfw.addWorkflowImplementationType(GreeterWorkflowImpl.class);
     wfw.start();
   }
}
```

HelloWorld には `GreeterWorker` に対応するものがないため、`GreeterWorker` という Java クラスをプロジェクトに追加し、そのファイルにコード例をコピーする必要があります。

最初のステップとして、[AmazonSimpleWorkflowClient](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html) オブジェクトを作成して設定します。このオブジェクトは基となる Amazon SWF サービスのメソッドを呼び出します。これを行うために、`GreeterWorker` で以下の操作を実行します。

1. [ClientConfiguration](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/ClientConfiguration.html) オブジェクトを作成し、ソケットのタイムアウトとして 70 秒を指定します。この値により、ソケットが閉じるまでに、確立したオープン接続でデータを転送する時間を指定します。

1. [BasicAWSCredentials](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/BasicAWSCredentials.html) オブジェクトを作成して AWS アカウントを識別し、アカウントキーをコンストラクタに渡します。利便性のためと、キーがコードでプレーンテキストとして公開されるのを避けるために、キーを環境変数として保存します。

1. ワークフローを表す [AmazonSimpleWorkflowClient](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html) オブジェクトを作成し、`BasicAWSCredentials` オブジェクトと `ClientConfiguration` オブジェクトをコンストラクタに渡します。

1. クライアントオブジェクトのサービスエンドポイントの URL を設定します。Amazon SWF は現在、すべての AWS リージョンで利用可能です。

便宜上、`GreeterWorker` では 2 つの文字列定数を定義します。
+ `domain` は、ワークフローの Amazon SWF ドメイン名を設定したときに作成した Amazon SWF アカウントです。`HelloWorldWorkflow` では、「helloWorldWalkthrough」ドメインのワークフローが実行されていることを前提としています。
+ `taskListToPoll` はタスクリストの名前です。ワークフローとアクティビティのワーカー間の通信を管理するために Amazon SWF で使用します。この名前として任意の便利な文字列を設定できます。HelloWorldWorkflow では、ワークフローとアクティビティの両方のタスクリストで「HelloWorldList」を使用します。バックグラウンドでは、これらの名前は最終的に別の名前空間に属するため、2 つのタスクリストは異なります。

`GreeterWorker` では、文字列定数と [AmazonSimpleWorkflowClient](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html) オブジェクトを使用してワーカーオブジェクトを作成し、アクティビティ/ワーカー実装と Amazon SWF 間のやり取りを管理します。特に、ワーカーオブジェクトでは適切なタスクリストでタスクをポーリングするタスクを処理します。

`GreeterWorker` は、`ActivityWorker` オブジェクトを作成し、新しいクラスインスタンスを追加して `GreeterActivitiesImpl` を処理するよう設定します。`GreeterWorker` はその後 `ActivityWorker` オブジェクトの `start` メソッドを呼び出します。これにより、指定されたアクティビティのタスクリストのポーリングを開始するようオブジェクトに指示します。

`GreeterWorker` では、`WorkflowWorker` オブジェクトを作成して設定し、クラスファイル名として `GreeterWorkflowImpl.class` を追加して `GreeterWorkflowImpl` を処理できるようにします。次に、`WorkflowWorker` オブジェクトの `start` メソッドを呼び出し、このオブジェクトに対して指定されたアクティビティタスクリストのポーリングを開始するよう指示します。

この時点で `GreeterWorker` を正常に実行できます。ワークフローとアクティビティが Amazon SWF に登録され、ワーカーオブジェクトによる各タスクリストのポーリングが開始されます。これを検証するには、`GreeterWorker` を実行し、Amazon SWF コンソールに移動して、ドメインのリストから `helloWorldWalkthrough` を選択します。**[Navigation]** (ナビゲーション) ペインで **[Workflow Types]** (ワークフロータイプ) を選択すると、`GreeterWorkflow.greet` が表示されるはずです。

![\[HelloWorldWorkflow ワークフロータイプ\]](http://docs.aws.amazon.com/ja_jp/amazonswf/latest/awsflowguide/images/Workflow_Type.png)


**[アクティビティタイプ]** を選択すると、`GreeterActivities` メソッドが表示されます。

![\[HelloWorldWorkflow アクティビティタイプ\]](http://docs.aws.amazon.com/ja_jp/amazonswf/latest/awsflowguide/images/Activity_Types.png)


ただし、**[Workflow Executions] (ワークフロー実行)** を選択すると、アクティブな実行は表示されません。ワークフローワーカーとアクティビティワーカーはタスクをポーリングしますが、ワークフロー実行はまだ開始していないためです。

## HelloWorldWorkflow スターター
<a name="getting-started-example-helloworldworkflow.starter"></a>

仕上げとして、ワークフロースターターを実装します。スターターは、ワークフロー実行を開始するアプリケーションです。実行状態は Amazon SWF で保存され、その履歴と実行ステータスを確認できるようになります。HelloWorldWorkflow では、ワークフロースターターを実装するために、次のように`GreeterMain` クラスを変更します。

```
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient;

public class GreeterMain {

   public static void main(String[] args) throws Exception {
     ClientConfiguration config = new ClientConfiguration().withSocketTimeout(70*1000);

     String swfAccessId = System.getenv("AWS_ACCESS_KEY_ID");
     String swfSecretKey = System.getenv("AWS_SECRET_KEY");
     AWSCredentials awsCredentials = new BasicAWSCredentials(swfAccessId, swfSecretKey);

     AmazonSimpleWorkflow service = new AmazonSimpleWorkflowClient(awsCredentials, config);
     service.setEndpoint("https://swf.us-east-1.amazonaws.com");

     String domain = "helloWorldWalkthrough";

     GreeterWorkflowClientExternalFactory factory = new GreeterWorkflowClientExternalFactoryImpl(service, domain);
     GreeterWorkflowClientExternal greeter = factory.getClient("someID");
     greeter.greet();
   }
}
```

`GreeterMain` は、まず `GreeterWorker` と同じコードを使用して `AmazonSimpleWorkflowClient` オブジェクトを作成します。次に、`GreeterWorkflowClientExternal` オブジェクトを作成します。このオブジェクトは、ワークフローのプロキシとして機能しますが、その方法は `GreeterWorkflowClientImpl` で作成したアクティビティクライアントがアクティビティメソッドのプロキシとして機能する方法とほぼ同じです。ワークフロークライアントオブジェクトを作成するには、`new` を使用しないで、次の手順に従います。

1. 外部クライアントのファクトリオブジェクトを作成し、`AmazonSimpleWorkflowClient` オブジェクトと Amazon SWF ドメイン名をコンストラクタに渡します。クライアントのファクトリオブジェクトは、フレームワークの注釈プロセッサで作成します。このプロセッサでは、ワークフローインターフェイス名に「ClientExternalFactoryImpl」と付加するだけでオブジェクト名を作成します。

1. 外部クライアントオブジェクトを作成するために、ファクトリオブジェクトの `getClient` メソッドを呼び出し、ワークフローインターフェイス名に「ClientExternal」と付加してオブジェクト名を作成します。オプションとして、`getClient` に文字列を渡します。Amazon SWF では、この文字列を使用して、このワークフローインスタンスを識別します。それ以外の場合、Amazon SWF は生成された GUID を使用してワークフローインスタンスを識別します。

ファクトリから返されるクライアントでは、[getClient](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/WorkflowClientFactoryExternal.html#getClient(java.lang.String)) メソッドに渡された文字列を名前に使用するワークフローのみを作成します (ファクトリから返されるクライアントはすでに Amazon SWF 内に状態があります)。別の ID のワークフローを実行するには、ファクトリに戻り、別の ID を指定して新しいクライアントを作成する必要があります。

ワークフロークライアントは `greet` メソッドを公開します。`GreeterMain` では、このメソッドを呼び出してワークフローを開始します。`@Execute` 注釈で指定した `greet()` メソッドと同様です。

**注記**  
注釈プロセッサでは、内部クライアントのファクトリオブジェクトも作成されます。このオブジェクトは、子ワークフローの作成に使用されます。詳細については、「[子ワークフロー実行](childworkflow.md)」を参照してください。

`GreeterWorker` がまだ実行中の場合は、これを一時的にシャットダウンして `GreeterMain` を実行します。これで、Amazon SWF コンソールのアクティブなワークフロー実行のリストに someID が表示されます。

![\[HelloWorldWorkflow ワークフロー実行\]](http://docs.aws.amazon.com/ja_jp/amazonswf/latest/awsflowguide/images/Active_Execution.png)


`someID` を選択して [**イベント**] タブを選択すると、イベントが表示されます。

![\[HelloWorldWorkflow の最初のワークフローイベント\]](http://docs.aws.amazon.com/ja_jp/amazonswf/latest/awsflowguide/images/Events1.png)


**注記**  
`GreeterWorker` を早く開始して、まだ実行中の場合は、後で説明する理由のために表示されるイベントリストが長くなります。`GreeterWorker` を停止し、`GreaterMain` の実行を再試行してください。

[**イベント**] タブには 2 つのイベントのみが表示されます。
+ `WorkflowExecutionStarted` は、ワークフローの実行を開始したことを示します。
+ `DecisionTaskScheduled` は、Amazon SWF が最初の決定タスクをキューに入れたことを示します。

最初の決定タスクでワークフローがブロックされた理由は、ワークフローは、2 つのアプリケーション (`GreeterMain` と `GreeterWorker`) 間で分散されたからです。`GreeterMain` によってワークフロー実行が開始されましたが、`GreeterWorker` が実行されていないため、ワーカーはリストのポーリングとタスクの実行を行いません。各アプリケーションは個別に実行できますが、最初の決定タスクを超えてワークフロー実行を進めるには両方のアプリケーションが必要です。ここで `GreeterWorker` を実行すると、ワークフローとアクティビティのワーカーはポーリングを開始し、さまざまなタスクが迅速に完了されます。ここで [`Events`] (イベント) タブを確認すると、最初のイベントのバッチが表示されます。

![\[HelloWorldWorkflow の詳細なワークフローイベント\]](http://docs.aws.amazon.com/ja_jp/amazonswf/latest/awsflowguide/images/Events2.png)


個別のイベントを選択して詳細情報を取得できます。確認が終わるまでに、ワークフローで「Hello World\$1」が コンソールに出力されます。

完了したワークフローは、アクティブな実行のリストに表示されなくなります。ただし、再確認する場合は、実行ステータスボタンの [**Closed**] (終了) を選択し、[**List Executions**] (実行の一覧表示) を選択できます。これにより、すべての完了したワークフローインスタンスのうち、ドメインの作成時に指定した保持期間を超えていないものが、指定したドメイン (`helloWorldWalkthrough`) に表示されます。

![\[HelloWorldWorkflow の完了済みワークフロー\]](http://docs.aws.amazon.com/ja_jp/amazonswf/latest/awsflowguide/images/Closed_Workflows.png)


各ワークフローインスタンスには [**Run ID**] (実行 ID) として一意の値が割り当てられています。異なるワークフローインスタンスに同じワークフロー ID を使用できますが、一度に 1 つのアクティブな実行に対してのみ使用できます。