Creating an Activity State Machine Using Step Functions
This tutorial shows you how to create an activity-based state machine using Java and Amazon Step Functions. Activities allow you to control worker code that runs somewhere else from your state machine. For an overview, see Activities in How Step Functions works.
To complete this tutorial, you need the following:
-
The SDK for Java
. The example activity in this tutorial is a Java application that uses the Amazon SDK for Java to communicate with Amazon. -
Amazon credentials in the environment or in the standard Amazon configuration file. For more information, see Set Up Your Amazon Credentials in the Amazon SDK for Java Developer Guide.
Topics
Step 1: Create an Activity
You must make Step Functions aware of the activity whose worker (a program) you want to create. Step Functions responds with an Amazon Resource Name(ARN) that establishes an identity for the activity. Use this identity to coordinate the information passed between your state machine and worker.
Important
Ensure that your activity task is under the same Amazon account as your state machine.
-
In the Step Functions console
, in the navigation pane on the left, choose Activities. -
Choose Create activity.
-
Enter an Activity Name, for example,
, and then choose Create Activity.get-greeting
-
When your activity task is created, make a note of its ARN, as shown in the following example.
arn:aws-cn:states:us-east-1:123456789012:activity:get-greeting
Step 2: Create a State Machine
Create a state machine that determines when your activity is invoked and when your worker should perform its primary work, collect its results, and return them.
-
In the Step Functions console
, in the navigation pane on the left, choose State machines. -
On the State machines page, choose Create state machine, and then choose Author with code snippets. For Type, choose Standard, and then enter a name for your state machine (for example,
.ActivityStateMachine
)Note
State machine, execution, and activity names must be 1–80 characters in length, must be unique for your account and Amazon Region, and must not contain any of the following:
-
Whitespace
-
Wildcard characters (
? *
) -
Bracket characters (
< > { } [ ]
) -
Special characters (
: ; , \ | ^ ~ $ # % & ` "
) -
Control characters (
\\u0000
-\\u001f
or\\u007f
-\\u009f
).
If your state machine is of type Express, you can provide the same name to multiple executions of the state machine. Step Functions generates a unique execution ARN for each Express state machine execution, even if multiple executions have the same name.
Step Functions allows you to create state machine, execution, and activity names that contain non-ASCII characters. These non-ASCII names don't work with Amazon CloudWatch. To ensure that you can track CloudWatch metrics, choose a name that uses only ASCII characters.
Under State machine definition, enter the following code, and include the ARN of the activity task that you created earlier in the
Resource
field, as shown in the following example.{ "Comment": "An example using a Task state.", "StartAt": "getGreeting", "Version": "1.0", "TimeoutSeconds": 300, "States": { "getGreeting": { "Type": "Task", "Resource": "
arn:aws-cn:states:us-east-1:123456789012:activity:get-greeting
", "End": true } } }This is a description of your state machine using the Amazon States Language. It defines a single
Task
state namedgetGreeting
. For more information, see State Machine Structure. -
-
Use the graph in the Visual Workflow pane to check that your Amazon States Language code describes your state machine correctly.
If you don't see the graph, choose
in the Visual Workflow pane.
-
Choose Next.
-
Create or enter an IAM role:
-
To create an IAM role for Step Functions, select Create an IAM role for me, and enter a Name for your role.
-
If you have previously created an IAM role with the correct permissions for your state machine, select Choose an existing IAM role. Select a role from the list, or provide an ARN for that role.
Note
If you delete the IAM role that Step Functions creates, Step Functions can't recreate it later. Similarly, if you modify the role (for example, by removing Step Functions from the principals in the IAM policy), Step Functions can't restore its original settings later.
-
-
Choose Create state machine.
Step 3: Implement a Worker
Create a worker. A worker is a program that is responsible for:
-
Polling Step Functions for activities using the
GetActivityTask
API action. -
Performing the work of the activity using your code, (for example, the
getGreeting()
method in the following code). -
Returning the results using the
SendTaskSuccess
,SendTaskFailure
, andSendTaskHeartbeat
API actions.
Note
For a more complete example of an activity worker, see Example Activity Worker in Ruby. This example provides an implementation based on best practices, which you can use as a reference for your activity worker. The code implements a consumer-producer pattern with a configurable number of threads for pollers and activity workers.
To implement the worker
-
Create a file named
GreeterActivities.java
. -
Add the following code to it.
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); } } } }
Note
The
EnvironmentVariableCredentialsProvider
class in this example assumes that theAWS_ACCESS_KEY_ID
(orAWS_ACCESS_KEY
) andAWS_SECRET_KEY
(orAWS_SECRET_ACCESS_KEY
) environment variables are set. For more information about providing the required credentials to the factory, see AWSCredentialsProvider in the Amazon SDK for Java API Reference and Set Up Amazon Credentials and Region for Development in the Amazon SDK for Java Developer Guide.By default the Amazon SDK will wait up to 50 seconds to receive data from the server for any operation. The
GetActivityTask
operation is a long-poll operation that will wait up to 60 seconds for the next available task. To prevent receiving aSocketTimeoutException
error, set SocketTimeout to 70 seconds. -
In the parameter list of the
GetActivityTaskRequest().withActivityArn()
constructor, replace theACTIVITY_ARN
value with the ARN of the activity task that you created earlier.
Step 4: Start an Execution
When you start the execution of the state machine, your worker polls Step Functions for activities, performs its work (using the input that you provide), and returns its results.
-
On the
ActivityStateMachine
page, choose Start execution.The New execution page is displayed.
(Optional) To identify your execution, you can specify a name for it in the Name box. By default, Step Functions generates a unique execution name automatically.
Note
Step Functions allows you to create state machine, execution, and activity names that contain non-ASCII characters. These non-ASCII names don't work with Amazon CloudWatch. To ensure that you can track CloudWatch metrics, choose a name that uses only ASCII characters.
-
In the execution input area, replace the example data with the following.
{ "who" : "Amazon Step Functions" }
-
Choose Start Execution.
A new execution of your state machine starts, and a new page showing your running execution is displayed.
-
In the Execution Details section, choose Info to view the Execution Status and the Started and Closed timestamps.
-
In the Execution Details section, expand the Output section to view the output of your workflow.
Step 5: Run and Stop the Worker
To have the worker poll your state machine for activities, you must run the worker.
-
On the command line, navigate to the directory in which you created
GreeterActivities.java
. -
To use the Amazon SDK, add the full path of the
lib
andthird-party
directories to the dependencies of your build file and to your JavaCLASSPATH
. For more information, see Downloading and Extracting the SDK in the Amazon SDK for Java Developer Guide. -
Compile the file.
$ javac GreeterActivities.java
-
Run the file.
$ java GreeterActivities
-
In the Step Functions console
, navigate to the Execution Details page. -
When the execution completes, choose Output to see the results of your execution.
-
Stop the worker.