WaterFlow is a non-magical / easy to understand / JDK8 framework for use with SWF
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



WaterFlow is a non-magical - relatively small framework for use with Amazon SWF.

Browse the online documentation


The framework is deeply routed in the original implementation of SWiFt which is a great example of achieving a very usable and simple SWF framework.

WaterFlow aims to add new features that are common in the AWS Flow Framework without the need for AspectJ and the magical annotation processing that occurs.

Here is a short list of philosophy decisions that differentiate this framework from SWiFt and Glisten

  1. JDK8 target - heavy use of new JDK8 features such as Optional and Streams make for simpler code
  2. Allow arbitrary types to be passed as input or sent as output for a given Activity through the use of a DataConverter
  3. Deciders are written through asynchronous interfaces - CompletionStage - without any magic!
  4. Heavy Heavy use of of the Immutables library


  1. Maven 2 or 3 installation
  2. Java 1.8+
  3. Active Amazon Web Services account and credentials
  4. Access to Amazon SWF with a domain set up
  5. Understanding of Amazon Simple Workflow concepts and the Amazon AWS SDK for Java


Several examples have been included within the com.github.fzakaria.waterflow.example package that demonstrate the full range of features offered by the framework.

You can use them as a learning example or even run them yourself. Included are some integration tests that verify that the workflows perform their expected operations. Take a look at the ExamplesIntegrationTest.java file.

Show me some code !

Talk is cheap, show me some code

public abstract  class ExampleActivities extends Activities {
    @ActivityMethod(name = "Addition", version = "1.0")
    public Integer addition(Integer lhs, Integer rhs) {
            return lhs + rhs;
public abstract class SimpleWorkflow extends Workflow<Integer, Integer> {

    final IntegerActivityAction step1 = IntegerActivityAction.builder().actionId(ActionId.of("step1"))
    public CompletionStage<Integer> decide(DecisionContext decisionContext) {
        // Set a breakpoint below to watch the decisions list to see what gets added on each call to Workflow.decide()
        CompletionStage<Integer> input = workflowInput(decisionContext.events());
        return input
                .thenCompose(i -> step1.withInput(i, 1).decide(decisionContext))
                .thenCompose(step1i -> step2.withInput(step1i, 100).decide(decisionContext));



  1. Write deciders in fluent Asynchronous interfaces using CompletionStage
  2. Many Actions supported in the deciders
  3. ActivityAction - Bread and butter of creating activities with generic input/out using DataConverter
  4. RecordMarkerAction - Record arbitrary diagnostic information during the decider to help debugging
  5. TimerAction - Create timers in the decider to wait for a specific time interval before proceeding
  6. WaitSignalAction - Wait on an external stimuli (could be human intervention) before proceeding in the workflow logic
  7. Extra long ActivityActions can emit a heartbeat to make sure they continue beyond acceptable time limit
  8. Automatically retry failed ActivityActions. Several retry strategies (including exponential backoff) provided.


  1. Add 'StartChildWorkflow' Action
  2. Add Send 'Signal' Action
  3. Add Spring/Guice as 'Optional' dependencies. Introduce appropriate new workflow scopes and sample configuration setup.
  4. Fixup some overuse of the Immutables library
  5. Add metrics