Menu
AWS Step Functions
Developer Guide

Creating an Activity State Machine

You can run task code on a state machine. This tutorial introduces you to creating an activity-based state machine using Java and AWS Step Functions.

To complete this tutorial you'll need the following:

  • The AWS SDK for Java. The example activity in this tutorial is a Java application that uses the AWS SDK for Java to communicate with AWS.

  • AWS credentials in the environment or in the standard AWS configuration file. For more information, see Set up Your AWS credentials in the AWS SDK for Java Developer Guide.

Step 1: Creating a New Activity

You must make Step Functions aware of the activity whose worker (a program) you want to create. Step Functions responds with an 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 AWS account as your state machine.

To create the new activity task

  1. Log in to the Step Functions console and choose Tasks.

  2. Choose Create new activity.

  3. On the Tasks page, type an Activity Name, for example get-greeting, and choose Create Activity.

  4. When your activity task is created, note its Amazon Resource Name (ARN), displayed on the right-hand side of the page, for example:

    Copy
    arn:aws:states:us-east-1:123456789012:activity:get-greeting

Step 2: Creating a State Machine

Create a state machine that will determine when your activity is invoked and when your worker should perform its primary work, collect its results, and return them.

To create the state machine

  1. Log in to the Step Functions console and choose Get Started.

    The Create a state machine page is displayed.

  2. Choose the Custom blueprint.

  3. In the box below Name your state machine type a name, for example ActivityStateMachine.

    Note

    State machine names must be 1-80 characters in length, must be unique for your account and region, and must not contain any of the following:

    • Whitespace

    • Whitespace characters (? *)

    • Bracket characters (< > { } [ ])

    • Special characters (: ; , \ | ^ ~ $ # % & ` ")

    • Control characters (\\u0000 - \\u001f or \\u007f - \\u009f).

  4. In the Code pane, add the following JSON text, using a Task state and the ARN of the activity task that you have created earlier in the Resource field, for example:

    Copy
    { "Comment": "An example using a Task state.", "StartAt": "getGreeting", "Version": "1.0", "TimeoutSeconds": 300, "States": { "getGreeting": { "Type": "Task", "Resource": "arn:aws: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 named getGreeting. For more information, see State Machine Structure.

  5. Choose Create State Machine.

    The IAM role for your state machine executions dialog box is displayed. Step Functions creates and selects an IAM role automatically.

    Note

    If you delete the IAM role that Step Functions creates, Step Functions can't re-create 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. For more information about creating an IAM role manually, see Creating IAM Roles for Use with AWS Step Functions.

  6. Choose OK.

    The state machine is created and an acknowledgement page is displayed.

Step 3: Implementing a Worker

Create a worker, a program which is responsible for the following:

  • 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 code below).

  • Returning the results using the SendTask* API actions.

To implement the worker

  1. Create a new file named GreeterActivities.java.

  2. Add the following code to it:

    Copy
    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 the AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY) environment variables are set. For more information about providing the required credentials to the factory, see AWSCredentialsProvider in the AWS SDK for Java API Reference and Set up AWS Credentials and Region for Development in the AWS SDK for Java Developer Guide.

    To give Step Functions sufficient time to process the request, setSocketTimeout is set to 70 seconds.

  3. In the parameter list of the GetActivityTaskRequest().withActivityArn() constructor, replace the ACTIVITY_ARN value with the ARN of the activity task that you have created earlier.

Step 4: Starting 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.

To start the execution

  1. In the Step Functions console, choose Dashboard and then choose the name of the state machine that you have created earlier.

  2. On the state machine's detail page, choose New execution.

    The New execution page is displayed.

  3. (Optional) To help identify your execution, you can enter an ID for it. To specify the ID, use the Enter your execution id here text box. If you don't enter an ID, Step Functions generates a unique ID automatically.

  4. In the execution input area, replace the example data with the following:

    Copy
    { "who" : "AWS Step Functions" }
  5. Choose Start Execution.

    A new execution of your state machine starts, and a new page showing your running execution is displayed.

Step 5: Running and Stopping the Worker

To have the worker poll your state machine for activities, you must run the worker.

After the execution completes, you should stop your worker. If you don't stop the worker, it will continue to run and poll for activities. When the execution is stopped, your worker has no source of tasks and generates a SocketTimeoutException during each poll.

To run and stop the worker

  1. On the command line, navigate to the directory in which you created GreeterActivities.java.

  2. To use the AWS SDK, add the full path of the lib and third-party directories to the dependencies of your build file and to your Java CLASSPATH. For more information, see Downloading and Extracting the SDK in the AWS SDK for Java Developer Guide.

  3. Compile the file:

    Copy
    $ javac GreeterActivities.java
  4. Run the file:

    Copy
    $ java GreeterActivities
  5. In the Step Functions console, navigate to the Execution Details page.

  6. When the execution completes, choose Output to see the results of your execution.

  7. Stop the worker.