この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、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
}
}
以上