# Flow execution

## Introduction

Once a flow has been defined, any number of executions of it can be launched in parallel at runtime. Execution of a flow is carried out by a dedicated system that is based internally on a state machine that runs atop the Java VM. As the life of a flow execution can span more than one request into the server, this system is also responsible for persisting execution state across requests.

This chapter documents Spring Web Flow's flow execution system. You will learn the core constructs of the system and how to execute flows out-of-container within a JUnit test environment.

## FlowExecution

A `org.springframework.webflow.execution.FlowExecution` is a runtime instantiation of a flow definition. Given a single `FlowDefinition`, any number of independent flow executions may be created. These executions are typically created by a `FlowExecutionFactory`.

A flow execution carries out the execution of program instructions defined within its definition in response to user events.

It may be helpful to think of a flow definition as analagous to a Java `Class`, and a flow execution as analagous to an object instance of that `Class`. Signaling an execution event can be considered analagous to sending an object a message.

### Flow execution creation

        FlowDefinition definition = ...
        FlowExecutionFactory factory = ...
        FlowExecution execution = factory.createFlowExecution(definition);

Once created, a new flow execution is initially inactive, waiting to be started. Once started, a flow execution becomes active by entering its `startState`. From there, it continues executing until it enters a state where user input is required to continue or it terminates.

### Flow execution startup

        ExternalContext context = ...
        execution.start(context);

When a flow execution reaches a state where input is required to continue, it is said to have paused, where it waits in that state for user input to be provided.

User input is provided by signaling an event that resumes the flow execution by communicating what user action was taken. Attributes of the signal event request form the basis for user input. The flow execution resumes by consuming the event.

Once a flow execution has resumed, it continues executing until it again enters a state where more input is needed or it terminates. Once a flow execution has terminated it becomes inactive and cannot be resumed.

### Flow execution resume

        ExternalContext context = ...
        execution.resume(context);
        if (execution.isActive()) {
            // still active but paused
        } else {
            // has ended
        }

### Flow execution lifecycle

As outlined, a flow execution can go through a number of phases throughout its lifecycle; for example, created, active, paused, ended.

Spring Web Flow gives you the ability to observe the lifecycle of an executing flow by implementing a `FlowExecutionListener`.

The different phases of a flow execution are shown graphically below:

Flow execution lifecycle

### Flow execution properties

The Spring Web Flow flow execution implementation is `org.springframework.webflow.engine.impl.FlowExecutionImpl`, typically created by a `FlowExecutionImplFactory` (a `FlowExecutionFactory` implementation). The configurable properties of this flow execution implementation are summarized below:

#### Flow Execution properties

Property name | Description | Cardinality | Default value
--- | --- | --- | ---
definition | The flow definition to be executed. | 1
listeners | The set of observers observing the lifecycle of this flow execution. | 0..* | Empty
attributes | Global system attributes that can be used to affect flow execution behavior | 0..* | Empty

The configurable constructs related to flow execution are shown graphically below:

Flow execution

### Flow execution impl creation

        FlowExecutionFactory factory = new FlowExecutionImplFactory();
        factory.setExecutionListeners(...);
        factory.setExecutionAttributes(...);
        FlowExecution execution = factory.createFlowExecution(definition);

## Flow execution context

Once created, a flow execution, representing the state of a flow at a point in time, maintains contextual state about itself that can be reasoned upon by clients. In addition, a flow execution exposes several data structures, called scopes, that allow clients to set arbitrary attributes that are managed by the execution.

The contextual properties associated with a flow execution are summarized below:

### Flow Execution Context properties

Property name | Description | Cardinality | Default value
--- | --- | --- | ---
active | A flag indicating if the flow execution is active. An inactive flow execution has either ended or has never been started. | 1
definition | The definition of the flow execution. The flow definition serves as the blueprint for the program. It may be helpful to think of a flow definition as like a `Class` and a flow execution as like an instance of that `Class`. This method may always be safely called. | 1
activeSession | The active flow session, tracking the flow that is currently executing and what state it is in. The active session can change over the life of the flow execution because a flow can spawn another flow as a subflow. This property can only be queried while the flow execution is active. | 1
conversationScope | A data map that forms the basis for "conversation scope". Arbitrary attributes placed in this map will be retained for the life of the flow execution and correspond to the length of the logical conversation. This map is shared by all flow sessions. | 1

As a flow execution is manipulated by clients its contextual state changes. Consider how contextual state is effected when the following events occur:

### An ordered set of events and their effects on flow execution context

Flow Execution Event | Active? | Value of the `activeSession` property
--- | --- | ---
created | false | Throws an IllegalStateException
started | true | A `FlowSession` whose `definition` is the top-level flow definition and whose `state` is the definition's start state.
state entered | true | A `FlowSession` whose `definition` is the top-level flow definition and whose `state` is the newly entered state.
subflow spawned | true | A `FlowSession` whose `definition` is the subflow definition and whose `state` is the subflow's start state.
subflow ended | true | A `FlowSession` whose `definition` is back to the top-level flow definition and whose `state` is the resuming state.
ended | false | Throws an IllegalStateException

As you can see, the `activeSession` of a flow execution changes when a subflow is spawned. Each flow execution maintains a stack of flow sessions, where each flow session represents a spawned instance of a flow definition. When a flow execution starts, the session stack initially consists of one (1) entry, an instance dubbed the root session. When a subflow is spawned, the stack increases to two (2) entries. When the subflow ends, the stack decreases back to one (1) entry. The active session is always the session at the top of the stack.

The contextual properties associated with a `FlowSession` are summarized below:

### Flow Session properties

Property name | Description | Cardinality | Default value
--- | --- | --- | ---
definition | The definition of the flow the session is an instance of. | 1
state | The current state of the session. | 1
status | A status indicator describing what the session is currently doing. | 1
scope | A data map that forms the basis for flow scope. Arbitrary attributes placed in this map will be retained for the scope of the flow session. This map is local to the session. | 1
flashMap | A data map that forms the basis for flash scope. Attributes placed in this map will be retained until the next external user event is signaled in the session. | 1

The following graphic illustrates an example flow execution context and flow session stack:

Flow execution context

In this illustration, a flow execution has been created for the `Book Flight` flow. The execution is currently active and the `activeSession` indicates it is in the `Display Seating Chart` state of the `Assign Seats` flow, which was spawned as a subflow from the `Enter Seat Assignments` state.

Note how the active session status is `paused`, indicating the flow execution is currently waiting for user input to be provided to continue. In this case, it is expected the user will choose a seat for their flight.

## Flow execution scopes

As alluded to, a flow execution manages several containers called scopes, which allow arbitrary attributes to be stored for a period of time. There are four scope types, each with different storage management semantics:

### Flow execution scope types

Scope type name | Management Semantics
--- | ---
request | Eligible for garbage collection when a single call into the flow execution completes.
flash | Cleared when the next user event is signaled into the flow session; eligible for garbage collection when the flow session ends.
flow | Eligible for garbage collection when the flow session ends.
conversation | Eligible for garbage collection when the root session of the governing flow execution (logical conversation) ends.

## Flow execution testing

Spring Web Flow provides support within the `org.springframework.webflow.test` package for testing flow executions with JUnit. This support is provided as convenience but is entirely optional, as a flow execution is instantiable in any environment with the standard Java `new` operator.

The general strategy for testing flows follows:

1. Your own implementations of definitional artifacts used by a flow such as actions, attribute mappers, and exception handlers should be unit tested in isolation. Spring Web Flow ships convenient stubs to assist with this, for instance `MockRequestContext`.

2. The execution of a flow should be tested as part of a system integration test. Such a test should exercise all possible paths of the flow, asserting that the flow responds to events as expected.

A flow execution integration test typically selects mock or stub implementations of application services called by the flow, though it may also exercise production implementations. Both are useful, supported system test configurations.

### Flow execution test example

To help illustrate testing a flow execution, first consider the following flow definition to search a phonebook for contacts:

Phonebook Search Flow - State Diagram

The corresponding XML-based flow definition implementation:

        <?xml version="1.0" encoding="UTF-8"?>
        <flow xmlns="http://www.springframework.org/schema/webflow"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="
                  http://www.springframework.org/schema/webflow
                  http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

            <start-state idref="enterCriteria"/>

            <view-state id="enterCriteria" view="searchCriteria">
                <render-actions>
                    <action bean="formAction" method="setupForm"/>
                </render-actions>
                <transition on="search" to="displayResults">
                    <action bean="formAction" method="bindAndValidate"/>
                </transition>
            </view-state>

            <view-state id="displayResults" view="searchResults">
                <render-actions>
                    <bean-action bean="phonebook" method="search">
                        <method-arguments>
                            <argument expression="flowScope.searchCriteria"/>
                        </method-arguments>
                        <method-result name="results"/>
                   </bean-action>
                </render-actions>
                <transition on="newSearch" to="enterCriteria"/>
                <transition on="select" to="browseDetails"/>
            </view-state>

            <subflow-state id="browseDetails" flow="detail-flow">
                <attribute-mapper>
                    <input-mapper>
                        <mapping source="requestParameters.id" target="id" from="string" to="long"/>
                    </input-mapper>
                </attribute-mapper>
                <transition on="finish" to="displayResults"/>
            </subflow-state>

        </flow>

Above you see a flow with three (3) states that execute these behaviors, respectively:

1. The first state `enterCriteria` displays a search criteria form so the user can enter who he or she wishes to search for.

2. On form submit and successful data binding and validation, the search is executed. After search execution a results view is displayed.

3. From the results view, the user may select a result they wish to browse additional details on or they may request a new search. On select, the "detail" flow is spawned and when it finishes the search is re-executed and it's results redisplayed.

From this behavior narrative the following assertable test scenarios can be extracted:

1. That when a flow execution starts, it enters the `enterCriteria` state and makes a `searchCriteria` view selection containing a form object to be used as the basis for form field population.

2. That on submit with valid input, the search is executed and a `searchResults` view selection is made.

3. That on submit with invalid input, the `searchCriteria` view is reselected.

4. That on newSearch, the `searchCriteria` view is selected.

5. That on select, the `detail` flow is spawned and passed the `id` of the selected result as expected.

To assist with writing these assertions, Spring Web Flow ships with JUnit-based flow execution test support within the `org.springframwork.webflow.test` package. These base test classes are indicated below:

#### Flow execution test support hierarchy

Class name | Description
--- | ---
AbstractFlowExecutionTests | The most generic base class for flow execution tests.
AbstractExternalizedFlowExecutionTests | The base class for flow execution tests whose flow is defined within an externalized resource, such as a file.
AbstractXmlFlowExecutionTests | The base class for flow execution tests whose flow is defined within an externalized XML resource.