Step FunctionsステートマシンのContextオブジェクトにアクセスしてみた
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、AWS Step FunctionsステートマシンのContextオブジェクトにアクセスしてみました。
Contextオブジェクトとは
Step FunctionsのContextオブジェクト(Context Object)を使用すれば、ステートマシン実行内でステートマシンの実行に関するコンテキストデータをJsonオブジェクトで取得できます。
取得できるContextオブジェクトを先にまとめると下記のようになります。
プロパティ(大) | 説明 | プロパティ(中) | 説明 |
---|---|---|---|
Execution | ステートマシンの実行 | Id | 実行ID |
Input | 実行入力 | ||
StartTime | 実行開始時間 | ||
Name | 実行名 | ||
RoleArn | 実行ロール | ||
StateMachine | ステートマシン | Id | ステートマシンID |
Name | ステートマシン名 | ||
State | ステート | Name | ステート名 |
EnteredTime | ステート開始時間 | ||
RetryCount | ステート再試行数 | ||
Map | マップ | Item.Index | 現在のアイテムのインデックス |
Item.Value | 現在のアイテムの値 |
これにより、ステートマシンの実行IDをタスク内で使用して後で追跡できるようにしたり、実行開始時間を別の処理に使えたりできるようになります。
やってみた
Contextオブジェクトにアクセスする
例として下記のようなステートマシンを作ってみました。Contextオブジェクトは$$
でアクセスできます。
{ "Comment": "A description of my state machine", "StartAt": "SNS Publish", "States": { "SNS Publish": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:sns:publish", "Parameters": { "Message": { "Context.$": "$$" }, "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic" }, "End": true } } }
ステートマシンを実行します。
実行結果のTaskScheduledの出力を見てみます。
Contextプロパティ配下で$$
からContextオブジェクトが取得できています。
{ "resourceType": "aws-sdk:sns", "resource": "publish", "region": "ap-northeast-1", "parameters": { "Message": { "Context": { "Execution": { "Id": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:execution:MyStateMachine2:f3daacd2-8397-bb5b-b7b0-ace372b4c2b7", "Input": { "Comment": "Insert your JSON here" }, "StartTime": "2021-12-06T14:47:32.223Z", "Name": "f3daacd2-8397-bb5b-b7b0-ace372b4c2b7", "RoleArn": "arn:aws:iam::XXXXXXXXXXXX:role/service-role/StepFunctions-MyStateMachine-role-f7ae852d" }, "StateMachine": { "Id": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:MyStateMachine2", "Name": "MyStateMachine2" }, "State": { "Name": "SNS Publish", "EnteredTime": "2021-12-06T14:47:32.281Z", "RetryCount": 0 } } }, "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic" }, "timeoutInSeconds": null, "heartbeatInSeconds": null }
Contextオブジェクト内の個別のプロパティにアクセスする
次にContextオブジェクト内の個別のプロパティにアクセスしてみます。
{ "Comment": "A description of my state machine", "StartAt": "SNS Publish", "States": { "SNS Publish": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:sns:publish", "Parameters": { "Message": { "ExecutionId.$": "$$.Execution.Id", "StateMachine.$": "$$.StateMachine", "StateEnteredTime.$": "$$.State.EnteredTime" }, "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic" }, "End": true } } }
個別のプロパティにアクセスできました。
{ "resourceType": "aws-sdk:sns", "resource": "publish", "region": "ap-northeast-1", "parameters": { "Message": { "StateMachine": { "Id": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:MyStateMachine2", "Name": "MyStateMachine2" }, "StateEnteredTime": "2021-12-06T15:02:50.599Z", "ExecutionId": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:execution:MyStateMachine2:9ad47ad2-f6ca-a41f-3838-b9313a60a3fd" }, "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic" }, "timeoutInSeconds": null, "heartbeatInSeconds": null }
MapステートのContextオブジェクトにアクセスする
ここまでは実行内のどのステートからでもアクセスできるContextでしたが、Mapステート内でのみアクセスできるContextもあります。
例として下記のような定義のステートマシンを作成しました。MapステートのContextオブジェクトはMapステートのParameter内で$$.Map
でアクセスできます。またMapステートのParameterはMap内のステートのParametersで使用できます。
{ "Comment": "A description of my state machine", "StartAt": "Map", "States": { "Map": { "Type": "Map", "ItemsPath": "$.mapped", "Parameters": { "Map.$": "$$.Map" }, "Iterator": { "StartAt": "SNS Publish", "States": { "SNS Publish": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:sns:publish", "Parameters": { "Message": { "Map.$": "$.Map" }, "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic" }, "End": true } } }, "End": true } } }
以下の入力を使用してステートマシンを実行します。
{ "mapped": [ { "message": "おはようございます。" }, { "message": "おやすみなさい。" } ] }
するとMapステートの実行結果のTaskStateEnteredで、Contextオブジェクトが取得できています。
MapステートではItemsPathで渡した配列がマップ処理されます。$$.Map
により配列内の各アイテムにアクセスできます。
{ "name": "SNS Publish", "input": { "Map": { "Item": { "Index": 0, "Value": { "message": "おはようございます。" } } } }, "inputDetails": { "truncated": false } }
以上