HelloWorldWorkflow アプリケーション - AWS Flow Framework Java 用

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

HelloWorldWorkflow アプリケーション

基本的なHelloWorld例はワークフローのように設定されていますが、いくつかの重要な点で Amazon SWF ワークフローとは異なります。

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

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

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

従来バージョンと Amazon SWF バージョンの Hello World!

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

HelloWorldWorkflow は AWS Flow Framework 、 for Java API を使用して実装されます。これにより、バックグラウンドで Amazon SWF とやり取りする際の複雑な詳細を処理し、開発プロセスを大幅に簡素化できます。for AWS Flow Framework Java アプリケーション用に既に設定されている HelloWorldで行ったのと同じプロジェクトを使用できます。ただし、アプリケーションを実行するには、Amazon SWF アカウントを以下のように設定する必要があります。

  • Amazon Web Services で、 AWS アカウントをまだお持ちでない場合はサインアップします。

  • アカウントのアクセス ID とシークレットキー ID を、AWS_ACCESS_KEY_ID 環境変数と AWS_SECRET_KEY 環境変数にそれぞれ割り当てます。コードのリテラルキー値は公開しないようお勧めします。環境変数に保存すると、問題に対処しやすくなります。

  • Amazon Simple Workflow Service で、Amazon SWF アカウントにサインアップします。

  • にログイン AWS Management Console し、Amazon SWF サービスを選択します。

  • 右上隅の [ドメインの管理] を選択し、新しい Amazon SWF ドメインを登録します。ドメインは、アプリケーションリソース (ワークフロータイプ、アクティビティタイプ、ワークフロー実行など) の論理コンテナです。任意の便利なドメイン名を使用できますが、チュートリアルではhelloWorldWalkthrough「」を使用します。

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

HelloWorldWorkflow アクティビティワーカー

HelloWorld は、アクティビティワーカーを単一のクラスとして実装しました。 AWS Flow Framework for Java アクティビティワーカーには、次の 3 つの基本コンポーネントがあります。

  • アクティビティメソッド — 実際のタスクを実行するこのメソッドは、インターフェイスで定義され、関連するクラスに実装されます。

  • ActivityWorker クラスは、アクティビティメソッドと 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 アプリケーション用です。インターフェイスの定義自体は変わっていないことに注意してください。ただし、インターフェイス定義 AWS Flow Framework には Java アノテーション @ActivityRegistrationOptions@Activitiesの 2 つの を適用する必要があります。注釈は設定情報を提供し、インターフェイス定義を使用してアクティビティクライアントクラスを生成するように AWS Flow Framework for Java 注釈プロセッサに指示します。これについては後で説明します。

@ActivityRegistrationOptions には、アクティビティの動作を設定するために使用されるいくつかの名前付き値があります。 は 2 つのタイムアウト HelloWorldWorkflow を指定します。

  • defaultTaskScheduleToStartTimeoutSeconds は、アクティビティのタスクリストでタスクをキューイングできる時間を指定します。300 秒 (5 分) に設定されています。

  • defaultTaskStartToCloseTimeoutSeconds は、アクティビティでタスクを実行する最大許容時間を指定します。10 秒に設定されています。

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

@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 ワークフローワーカー

Amazon SWF ワークフローワーカーには 3 つの基本コンポーネントがあります。

  • ワークフロー実装は、ワークフロー関連のタスクを実行するクラスです。

  • アクティビティクライアントクラスは、基本的にアクティビティクラスのプロキシであり、アクティビティメソッドを非同期的に実行するためにワークフロー実装で使用されます。

  • ワークフローと Amazon SWF 間の相互作用を管理するWorkflowWorkerクラス。

このセクションでは、ワークフロー実装とアクティビティクライアントについて説明します。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 アプリケーションに不可欠です。ワークフローインターフェイス定義 AWS Flow Framework には、Java アノテーション @Workflow@WorkflowRegistrationOptionsの 2 つの を適用する必要があります。注釈は設定情報を提供し、後で説明するように、 for Java AWS Flow Framework 注釈プロセッサにインターフェイスに基づいてワークフロークライアントクラスを生成するように指示します。

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

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

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

@Execute には 2 つの目的があります。

  • ワークフローのエントリポイントとして greet を識別します。これは、ワークフローを開始するために、ワークフロースターターで呼び出すメソッドです。通常、エントリポイントには 1 つ以上のパラメータを設定できます。これにより、スターターはワークフローを初期化できます。ただし、この例では初期化が不要です。

  • ワークフローのバージョン番号を指定します。これにより、世代が異なるワークフロー実装を追跡できます。ワークフローインターフェイスを Amazon SWF に登録した後で変更する (タイムアウト値を変更するなど) には、新しいバージョン番号を使用する必要があります。

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

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 は、ローカルで 1 つのプロセスとして実行される標準 Java アプリケーションです。 は、 のインスタンスを作成しGreeterActivitiesImpl、メソッドを順番に呼び出し、あるアクティビティから次のアクティビティに戻り値を渡すだけで、ワークフロートポロジを実装GreeterWorkflowImplできます。Amazon SWF ワークフローの場合も同様に、アクティビティのタスクは GreeterActivitiesImpl のアクティビティメソッドで実行されます。ただし、このメソッドはワークフローと同じプロセスで実行されない場合があります。同じシステムで実行されない場合さえあります。したがって、ワークフローではアクティビティを非同期的に実行する必要があります。以上の要件に伴って以下の問題が生じします。

  • 異なるプロセス (異なるシステムの場合もある) で実行されている可能性があるアクティビティメソッドを実行する方法。

  • アクティビティメソッドを非同期的に実行する方法。

  • アクティビティの入力と戻り値を管理する方法。たとえば、アクティビティ A の戻り値がアクティビティ B への入力である場合、アクティビティ A が完了するまでアクティビティ B の実行をブロックする必要があります。

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

アクティビティクライアント

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

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 アクティビティワーカー」を参照してください。

注記

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

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

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

HelloWorldWorkflow ワークフローとアクティビティの実装

ワークフローとアクティビティの実装には、ワーカークラス ActivityWorkerと が関連付けられていますWorkflowWorker。これらのワーカークラスでは、Amazon SWF とアクティビティ/ワークフロー実装の間の通信を処理するために、適切な Amazon SWF タスクリストでタスクをポーリングし、各タスクの適切なメソッドを実行して、データフローを管理します。詳細については、「AWS Flow Framework 基本概念: アプリケーション構造」を参照してください。

アクティビティ/ワーカー実装と対応するワーカーオブジェクトを関連付けるには、以下の操作を行うワーカーアプリケーションを 1 つ以上実装します。

  • ワークフローまたはアクティビティを Amazon SWF に登録する。

  • ワーカーオブジェクトを作成してワークフローまたはアクティビティのワーカー実装に関連付ける。

  • Amazon SWF との通信を開始するようワーカーオブジェクトに指示する。

ワークフローとアクティビティを別個のプロセスとして実行する場合は、ワークフローとアクティビティのワーカーホストを別個に実装する必要があります。例については、HelloWorldWorkflowDistributed アプリケーションを参照してください。簡素化のため、 HelloWorldWorkflow は、アクティビティワーカーとワークフローワーカーを同じプロセスで実行する単一のワーカーホストを次のように実装します。

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(); } }

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

最初のステップでは、基盤となる Amazon SWF サービスメソッドを呼び出す AmazonSimpleWorkflowClient オブジェクトを作成して設定します。これを行うために、GreeterWorker で以下の操作を実行します。

  1. ClientConfiguration オブジェクトを作成し、70 秒のソケットタイムアウトを指定します。この値により、ソケットが閉じるまでに、確立したオープン接続でデータを転送する時間を指定します。

  2. Basic AWSCredentials オブジェクトを作成して AWS アカウントを識別し、アカウントキーをコンストラクターに渡します。利便性のためと、キーがコードでプレーンテキストとして公開されるのを避けるために、キーを環境変数として保存します。

  3. ワークフローを表すAmazonSimpleWorkflowClientオブジェクトを作成し、 BasicAWSCredentialsおよび ClientConfiguration オブジェクトをコンストラクターに渡します。

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

便宜上、GreeterWorker では 2 つの文字列定数を定義します。

  • domain はワークフローの Amazon SWF ドメイン名で、Amazon SWF アカウントの設定時に作成したものです。 は、helloWorldWalkthrough「」ドメインでワークフローを実行していることをHelloWorldWorkflow前提としています。

  • taskListToPoll はタスクリストの名前です。ワークフローとアクティビティのワーカー間の通信を管理するために Amazon SWF で使用します。この名前として任意の便利な文字列を設定できます。 HelloWorldWorkflow は、ワークフローとアクティビティの両方のタスクリストにHelloWorldList「」を使用します。バックグラウンドでは、これらの名前は最終的に別の名前空間に属するため、2 つのタスクリストは異なります。

GreeterWorker は、文字列定数と AmazonSimpleWorkflowClient オブジェクトを使用してワーカーオブジェクトを作成します。これにより、アクティビティとワーカー実装と 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 ワークフロータイプ

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

HelloWorldWorkflow アクティビティタイプ

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

HelloWorldWorkflow スターター

仕上げとして、ワークフロースターターを実装します。スターターは、ワークフロー実行を開始するアプリケーションです。実行状態は 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 ドメイン名をコンストラクタに渡します。Client Factory オブジェクトは、フレームワークの注釈プロセッサによって作成されます。このプロセッサは、ワークフローインターフェイス名ClientExternalFactoryImplに「」を追加するだけでオブジェクト名を作成します。

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

ファクトリから返されるクライアントでは、getClient メソッドに渡された文字列を名前に使用するワークフローのみを作成します (ファクトリから返されるクライアントはすでに Amazon SWF 内に状態があります)。別の ID のワークフローを実行するには、ファクトリに戻り、別の ID を指定して新しいクライアントを作成する必要があります。

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

注記

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

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

HelloWorldWorkflow ワークフロー実行

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

HelloWorldWorkflow 初期ワークフローイベント
注記

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

[イベント] タブには 2 つのイベントのみが表示されます。

  • WorkflowExecutionStarted は、ワークフローの実行を開始したことを示します。

  • DecisionTaskScheduled は、Amazon SWF が最初の決定タスクをキューに入れたことを示します。

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

HelloWorldWorkflow ワークフローイベントの完了

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

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

HelloWorldWorkflow 完了したワークフロー

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