[[statemachine]]
= Using Spring Statemachine

This part of the reference documentation explains the core functionality
that Spring Statemachine provides to any Spring based application.

<<sm-config>> the generic configuration support.

<<sm-factories>> the generic state machine factory support.

<<sm-actions>> the actions support.

<<sm-guards>> the guard support.

<<sm-extendedstate>> the extended state support.

<<sm-statecontext>> the state context support.

<<sm-triggers>> the use of triggers.

<<sm-listeners>> the use of state machine listeners.

<<sm-context>> the generic Spring application context support.

<<sm-accessor>> the state machine internal accessor support.

<<sm-interceptor>> the state machine error handling support.

<<sm-error-handling>> the state machine interceptor support.

<<sm-persist>> the state machine persisting support.

<<sm-distributed>> the distributed state machine support.

<<sm-test>> the state machine testing support.

[[sm-config]]
== Statemachine Configuration
One of the common tasks when using a Statemachine is to design its
runtime configuration. This chapter will focus on how Spring
Statemachine is configured and how it leverages Spring's lightweight
IoC containers to simplify the application internals to make it more
manageable.

[NOTE]
====
Configuration examples in this section are not feature complete, i.e.
you always need to have definitions of both states and transitions,
otherwise state machine configuration would be ill-formed. We have
simply made code snippets less verbose by leaving other needed parts
away.
====

[[statemachine-config-annotations]]
=== Using _enable_ annotations
We use familiar spring _enabler_ annotations to ease configuration. Two
annotations exists, _@EnableStateMachine_ and _@EnableStateMachineFactory_.
These annontations if placed in a _@Configuration_ class will enable
some basic functionality needed by a state machines.

_@EnableStateMachine_ is used when a configuration wants to create an
instance of a _StateMachine_. Usually _@Configuration_ class extends adapters
`EnumStateMachineConfigurerAdapter` or `StateMachineConfigurerAdapter` which
allows user to override configuration callback methods. We automatically
detect if user is using these adapter classes and modify runtime configuration
logic.

_@EnableStateMachineFactory_ is used when a configuration wants to create an
instance of a _StateMachineFactory_.

[NOTE]
====
Usage examples of these are shown in below sections.
====

[[statemachine-config-states]]
=== Configuring States
We'll get into more complex configuration examples a bit later but
let's first start with a something simple. For most simple state
machine you just use `EnumStateMachineConfigurerAdapter` and define
possible states, choose initial and optional end state.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetAA]
----

It's also possible to use strings instead of enums as states and
events by using `StateMachineConfigurerAdapter` as shown below. Most
of a configuration examples is using enums but generally speaking
strings and enums can be just interchanged.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetAB]
----

[NOTE]
====
Using enums will bring more safe set of states and event types but
limits possible combinations to compile time. Strings don't have this
limitation and allows user to use more dynamic ways to build state
machine configurations but doesn't allow same level of safety.
====

=== Configuring Hierarchical States
Hierarchical states can be defined by using multiple `withStates()`
calls where `parent()` can be used to indicate that these
particular states are sub-states of some other state.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetB]
----

=== Configuring Regions

There are no special configuration methods to mark a collection of
states to be part of an orthogonal state. To put it simple, orthogonal
state is created when same hierarchical state machine has multiple set
of states each having a initial state. Because an individual state
machine can only have one initial state, multiple initial states must
mean that a specific state must have multiple independent regions.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetP]
----

=== Configuring Transitions
We support three different types of transitions, `external`,
`internal` and `local`. Transitions are either triggered by a signal
which is an event sent into a state machine or a timer.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetC]
----

=== Configuring Guards
Guards are used to protect state transitions. Interface _Guard_ is
used to do an evaluation where method has access to a _StateContext_.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetD]
----

In above two different types of guard configurations are used. Firstly a
simple _Guard_ is created as a bean and attached to transition between
states `S1` and `S2`.

Secondly a simple SPeL expression can be used as a guard where
expression must return a `BOOLEAN` value. Behind a scenes this
expression based guard is a _SpelExpressionGuard_. This was attached to
transition between states `S2` and `S3`. Both guard in above sample
always evaluate to true.

=== Configuring Actions
Actions can be defined to be executed with transitions and states
itself. Action is always executed as a result of a transition which
originates from a trigger.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetEA]
----

In above a single `Action` is defined as bean `action` and associated
with a transition from `S1` to `S2`.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetEB]
----

[NOTE]
====
Usually you would not define same `Action` instance for different
stages but we did it here not to make too much noise in a code
snippet.
====

In above a single `Action` is defined as bean `action` and associated
with states `S1`, `S2` and `S3`. There is more going on there which
needs more clarification:

* We defined action for initial state `S1`.
* We defined entry action for state `S1` and left exit action empty.
* We defined exit action for state `S2` and left entry action empty.
* We defined entry action as well as exit action for state `S3`.
* Notice how state `S1` is used twice with `initial()` and `state()`
  functions. This is only needed if you want to define entry or exit
  actions with initial state.

[IMPORTANT]
====
Defining action with `initial()` function only executes particular
action when state machine or sub state is started. Think this action
to be initializing action which is only executed once. Action defined
with `state()` is then executed if state machine is transitioning back
and forward between initial and non-inital states.
====

=== Configuring Pseudo States

_Pseudo state_ configuration is usually done by configuring states and
transitions. Pseudo states are automatically added to state machine as
states.

==== Initial State
Simply mark a particular state as initial state by using `initial()`
method. There are two methods where one takes extra argument to define
an initial action. This initial action is good for example initialize
extended state variables.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetQ]
----

==== Terminate State
Simply mark a particular state as end state by using `end()` method.
This can be done max one time per individual sub-machine or region.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetAA]
----

==== History State
History state can be defined once for each individual state machine.
You need to choose its state identifier and `History.SHALLOW` or
`History.DEEP` respectively.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetR]
----

==== Choice State
Choice needs to be defined in both states and transitions to work
properly. Mark particular state as choice state by using `choice()`
method. This state needs to match source state when transition is
configured for this choice.

Transition is configured using `withChoice()` where you define source
state and `first/then/last` structure which is equivalent to normal
`if/elseif/else`. With `first` and `then` you can specify a guard just
like you'd use a condition with `if/elseif` clauses.

Transition needs to be able to exist so make sure `last` is used.
Otherwise configuration is ill-formed.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetS]
----

==== Fork State
Fork needs to be defined in both states and transitions to work
properly. Mark particular state as choice state by using `fork()`
method. This state needs to match source state when transition is
configured for this fork.

Target state needs to be a super state or immediate states in
regions. Using a super state as target will take all regions into
initial states. Targeting individual state give more controlled entry
into regions.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetT]
----

==== Join State
Join needs to be defined in both states and transitions to work
properly. Mark particular state as choice state by using `join()`
method. This state doesn't need to match either source states or
target state in a transition configuration.

Select one target state where transition goes when all source states
has been joined. If you use state hosting regions as source, end
states of a regions are used as joins. Otherwise you can pick any
states from a regions.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetU]
----

[[statemachine-config-commonsettings]]
=== Configuring Common Settings
Some of a common state machine configuration can be set via a
`ConfigurationConfigurer`. This allows to set `BeanFactory`,
`TaskExecutor`, `TaskScheduler`, autostart flag for a state machine
and register `StateMachineListener` instances.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetYA]
----

State machine `autoStartup` flag is disabled by default because all
instances handling sub-states are controlled by a state machine itself
and cannot be started automatically. Also it is much safer to leave
this decision to a user whether a machine should be started
automatically or not. This flag will only control an autostart of a
top-level state machine.

Setting a `BeanFactory`, `TaskExecutor` or `TaskScheduler` exist for
conveniance for a user and are also use within a framework itself.

Registering `StateMachineListener` instances is also partly for
convenience but is required if user wants to catch callback during a
state machine lifecycle like getting notified of a state machine
start/stop events. Naturally it is not possible to listen a state
machine start events if `autoStartup` is enabled unless listener can
be registered during a configuration phase.

`DistributedStateMachine` is configured via `withDistributed()` which
allows to set a `StateMachineEnsemble` which if exists automatically
wraps created `StateMachine` with `DistributedStateMachine` and
enables distributed mode.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetYB]
----

More about distributed states, refer to section <<sm-distributed>>.

[[sm-factories]]
== State Machine Factories
There are use cases when state machine needs to be created dynamically
instead of defining static configuration at compile time. For example
if there are custom components which are using its own state machines
and these components are created dynamically it is impossible to have
a static state machined build during the application start. Internally
state machines are always build via a factory interfaces and this then
gives user an option to use this feature programmatically.
Configuration for state machine factory is exactly same as you've seen
in various examples in this document where state machine configuration
is hard coded.

=== Factory via Adapter
Actually creating a state machine using _@EnableStateMachine_ will
work via factory so _@EnableStateMachineFactory_ is merely exposing
that factory via its interface.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetFA]
----

Now that you've used _@EnableStateMachineFactory_ to create a factory
instead of a state machine bean, it can be injected and used as is to
request new state machines.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetL]
----

==== Adapter Factory Limitations
Current limitation of factory is that all actions and guard it is
associating with created state machine will share a same instances.
This means that from your actions and guard you will need to
specifically handle a case that same bean will be called by a different
state machines. This limitation is something which will be resolved in
future releases.

=== State Machine via Builder
Using adapters shown above has a limitation imposed by its
requirement to work via Spring `@Configuration` classes and
application context. While this is a very clear model to configure a
state machine instances it will limit configuration at a compile time
which is not always what a user wants to do. If there is a requirement
to build more dynamic state machines, a simple builder pattern can be
used to construct similar instances. Using strings as states and
events this builder pattern can be used to build fully dynamic state
machines outside of a Spring application context as shown above.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetFB]
----

Builder is using same configuration interfaces behind the scenes that
the `@Configuration` model using adapter classes. Same model goes to
configuring transitions, states and common configuration via builder's
methods. This simply means that whatever you can use with a normal
`EnumStateMachineConfigurerAdapter` or `StateMachineConfigurerAdapter`
can be used dynamically via a builder.

[NOTE]
====
Currently `builder.configureStates()`, `builder.configureTransitions()`
and `builder.configureConfiguration()` interface methods cannot be
chained together meaning builder methods needs to be called individually.
====

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetFC]
----

It is important to understand on what cases common configuration needs
to be used with a machines instantiated from a builder. Configurer
returned from a `withConfiguration()` can be used to setup _autoStart_,
_TaskScheduler_, _TaskExecutor_, _BeanFactory_ and additionally register
a _StateMachineListener_. If _StateMachine_ instance returned from
a builder is registered as a bean via `@Bean`, i.e. _BeanFactory_
is attached automatically and then a default _TaskExecutor_ can be found
from there. If instances are used outside of a spring application context
these methods must be used to setup needed facilities.

[[sm-deferevents]]
== Using Deferred Events
When en event is sent it may fire an `EventTrigger` which then may cause
a transition to happen if a state machine is in a state where trigger is
evaluated successfully. Normally this may lead to a situation where
an event is not accepted and is dropped. However it may be desirable to
postpone this event until a state machine enters other state, in which
it is possible to accept that event. In other words an event simply
arrives at an inconvenient time.

Spring Statemachine provides a mechanism for deferring events for later
processing. Every state can have a list of deferred events. If an event
in the current state’s deferred event list occurs, the event will be saved
(deferred) for future processing until a state is entered that does not list
the event in its deferred event list. When such a state is entered, the
state machine will automatically recall any saved events that are no longer
deferred and will then either consume or discard these events. It is possible
for a superstate to have a transition defined on an event that is deferred
by a substate. Following same hierarchical state machines concepts, the substate
takes precedence over the superstate, the event will be deferred and the
transition for the superstate will not be executed. With orthogonal regions
where one orthogonal region defers an event and another accepts the event, the
accept takes precedence and the event is consumed and not deferred.

The most obvious use case for event deferring is when an event is causing
a transition into a particular state and state machine is then returned back
to its original state where second event should cause a same transition. Lets
take this with a simple example.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests2.java[tags=snippetE]
----

In above state machine has state _READY_ which indicates that machine is
ready to process events which would take it into a _DEPLOY_ state where the
actual deployment would happen. After deploy actions has been executed machine
is then returned back into a _READY_ state. Sending multiple events in a
_READY_ state is not causing any trouble if machine is using synchronous executor
because event sending would block between event calls. However if executor is using
threads then other events may get lost because machine is no longer in a state where
event could be processed. Thus deferring some of these events allows machine to
preserve these events.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests2.java[tags=snippetF]
----

In above state machine which is using nested states instead of a flat
state model, event _DEPLOY_ can be deferred directly in a substate.
It is also showing concept of deferring event _DONE_ in one of a
sub-states which would then override anonymous transition between
_DEPLOY_ and _DONE_ states if state machine happens to be in a
_DEPLOYPREPARE_ state when _DONE_ event is dispatched. In
_DEPLOYEXECUTE_ state _DONE_ event is not deferred, thus event would
be handled in a super state.

[[sm-scopes]]
== Using Scopes
Support for scopes in a state machine is very limited but it is possible
to enable use of _session_ scope using a normal spring `@Scope` annotation.
Firstly if state machine is build manually via a builder and returned into
context as `@Bean`, and secondly via an contifuration adapter. Both of
these simply needs an a `@Scope` to be present where _scopeName_ is set to
_session_ and _proxyMode_ to `ScopedProxyMode.TARGET_CLASS`. Examples for
both use cases are shown below.

[TIP]
====
See sample <<statemachine-examples-scope>> how to use session scoping.
====

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests2.java[tags=snippetB]
----

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests2.java[tags=snippetC]
----

Once you have scoped state machine into `session`, autowiring it into
a `@Controller` will give new state machine instance per session.
State machine is then destroyed when `HttpSession` is invalidated.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests2.java[tags=snippetD]
----

[NOTE]
====
Using state machines in a `session` scopes needs a careful planning
mostly because it is a relatively heavy component.
====

[NOTE]
====
Spring Statemachine poms don't have any dependencies to Spring MVC
classes which you will need to work with session scope. But if you're
working with a web application, you've already pulled those deps
directly from Spring MVC or Spring Boot.
====

[[sm-actions]]
== Using Actions
Actions are one of the most useful components from user perspective to
interact and collaborate with a state machine. Actions can be executed
in various places in a state machine and its states lifecycle like
entering or exiting states or during a transitions.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetVA]
----

Above `action1` and `action2` beans are attached to states entry and
exit respectively.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetVD]
----

You can directly implement _Action_ as an anonymous function or create
a your own implementation and define appropriate implementation as a
bean.

In `action3` a SpEL expression is used to send event *Events.E1* into
a state machine.

[NOTE]
====
_StateContext_ is described in section <<sm-statecontext>>.
====

=== SpEL Expressions with Actions 
It is also possible to use SpEL expressions as a replacement for a
full _Action_ implementation.

[[sm-guards]]
== Using Guards
Above `guard1` and `guard2` beans are attached to states entry and
exit respectively.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetVB]
----

You can directly implement _Guard_ as an anonymous function or create
a your own implementation and define appropriate implementation as a
bean. In above sample `guardExpression` is simply checking if extended
state variable `myvar` evaluates to _TRUE_.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetVC]
----

[NOTE]
====
_StateContext_ is described in section <<sm-statecontext>>.
====

=== SpEL Expressions with Guards
It is also possible to use SpEL expressions as a replacement for a
full _Guard_ implementation. Only requirement is that expression needs
to return a *Boolean* value to satisfy _Guard_ implementation. This is
demonstrated with a _guardExpression()_ function which takes an
expression as an argument.

[[sm-extendedstate]]
== Using Extended State
Let's assume that we'd need to create a state machine tracking how
many times a user is pressing a key on a keyboard and then terminate
when keys are pressed 1000 times. Possible but a really naive solution
would be to create a new state for each 1000 key presses. Going
even worse combinations you might suddenly have astronomical number of
states which naturally is not very practical.

This is where extended state variables comes into rescue by not having
a necessity to add more states to drive state machine changes, instead
a simple variable change can be done during a transition.

`StateMachine` has a method `getExtendedState()` which returns an
interface `ExtendedState` which gives an access to extended state
variables. You can access variables directly via a state machine or
`StateContext` during a callback from actions or transitions.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippet7]
----

If there is a need to get notified for extended state variable
changes, there are two options; either use `StateMachineListener` and
listen `extendedStateChanged(key, value)` callbacks:


[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippet5]
----

Or implement a Spring Application context listeners for
`OnExtendedStateChanged`. Naturally as mentioned in <<sm-listeners>>
you can also listen all `StateMachineEvent` events.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippet6]
----

[[sm-statecontext]]
== Using StateContext
_StateContext_ is a domain object representing a current status of a
state machine within a transition or an action. Context gives an
access to a various information like event, message headers, extended
state variables, current transition and a top-level state machine in
case there is a need to send events to a further processing.

[[sm-triggers]]
== Triggering Transitions
Driving a statemachine is done via transitions which are triggered
by triggers. Currently supported triggers are _EventTrigger_ and
_TimerTrigger_.

=== EventTrigger
_EventTrigger_ is the most useful trigger because it allows user to
directly interact with a state machine by sending events to it. These
events are also called signals. Trigger is added to a transition simply
by associating a state to it during a configuration.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetO]
----
In above example we send an event using two different ways. Firstly we
simply sent a type safe event using state machine api method
`sendEvent(E event)`. Secondly we send event wrapped in a Spring
messaging _Message_ using api method `sendEvent(Message<E> message)`
with a custom event headers. This allows user to add arbitrary extra
information with an event which is then visible to _StateContext_ when
for example user is implementing actions.

=== TimerTrigger
_TimerTrigger_ is useful when something needs to be triggered
automatically without any user interaction. `Trigger` is added to a
transition by associating a timer with it during a configuration.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests2.java[tags=snippetA]
----

In above we have two states, `S1` and `S2`. We have a normal external
transition from `S1` to `S2` with event `E1` but interesting part is
when we define internal transition with source state `S2` and
associate it with `Action` bean `timerAction` and `timer` value of
`1000ms`. Once a state machine receive event `E1` it does a transition
from `S1` to `S2` and timer kicks in. As long as state is kept in `S2`
`TimerTrigger` executes and causes a transition associated with that
state which in this case is the internal transition which has the
`timerAction` defined.

[[sm-listeners]]
== Listening State Machine Events
There are use cases where you just want to know what is happening with
a state machine, react to something or simply get logging for
debugging purposes. SSM provides interfaces for adding listeners which
then gives an option to get callback when various state changes,
actions, etc are happening.

You basically have two options, either to listen Spring application
context events or directly attach listener to a state machine. Both of
these basically will provide same information where one is producing
events as event classes and other producing callbacks via a listener
interface. Both of these have pros and cons which will be discussed later.

=== Application Context Events
Application context events classes are _OnTransitionStartEvent_,
_OnTransitionEvent_, _OnTransitionEndEvent_, _OnStateExitEvent_,
_OnStateEntryEvent_, _OnStateChangedEvent_, _OnStateMachineStart_ and
_OnStateMachineStop_ and others which extends base event class
_StateMachineEvent_ These can be used as is with spring typed
_ApplicationListener_.

_StateMachine_ will send context events via _StateMachineEventPublisher_
it's set. Default implementation is automatically created if _@Configuration_
class is annotated with _@EnableStateMachine_.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetG]
----

Context events are also automatically enabled via _@EnableStateMachine_
with machine builder _StateMachine_ registered as a bean as shown below.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetGG]
----

=== State Machine Listener
Using _StateMachineListener_ you can either extend it and
implement all callback methods or use _StateMachineListenerAdapter_
class which contains stub method implementations and choose which ones
to override.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetH]
----

In above example we simply created our own listener class
_StateMachineEventListener_ which extends
_StateMachineListenerAdapter_.

Once you have your own listener defined, it can be registered into a
state machine via its interface as shown below. It's just a matter of
flavour if it's hooked up within a spring configuration or done
manually at any time of application life-cycle.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetM]
----

=== Limitations and Problems
Spring application context is not a fastest eventbus out there so it
is advised to give some thought what is a rate of events state machine
is sending. For better performance it may be better to use
_StateMachineListener_ interface. For this specific reason it is
possible to use `contextEvents` flag with _@EnableStateMachine_ and
_@EnableStateMachineFactory_ to disable Spring application context
events as shown above.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetN]
----

[[sm-context]]
== Context Integration
It is a little limited to do interaction with a state machine by
either listening its events or using actions with states and
transitions. Time to time this approach would be too limited and
verbose to create interaction with the application a state machine is
working with. For this specific use case we have made a spring style
context integration which easily attach state machine functionality
into your beans.

=== Annotation Support
_@WithStateMachine_ annotation can be used to associate a state
machine with a existing bean. Within this annotation a property's
_source_ and _target_ can be used to qualify a transition. If
_source_ and _target_ is left empty then any transition is matched.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetI]
----

Default _@OnTransition_ annotation can't be used with a state and
event enums user have created due to java language limitations, thus
string representation have to be used.

Additionally it is possible to access `Event Headers` and
`ExtendedState` by adding needed arguments to a method. Method
is then called automatically with these arguments.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetII]
----

However if you want to have a type safe annotation it is possible to
create a new annotation and use _@OnTransition_ as meta annotation.
This user level annotation can make a reference to actual states and
events enums and framework will try to match these in a same way.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetJ]
----

Above we created a _@StatesOnTransition_ annotation which defines
`source` and `target` as a type safe manner.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetK]
----

In your own bean you can then use this _@StatesOnTransition_ as is and
use type safe `source` and `target`.

[[sm-accessor]]
== State Machine Accessor
`StateMachine` is a main interface to communicate with a state machine
itself. Time to time there is a need to get more dynamical and
programmatic access to internal structures of a state machine and its
nested machines and regions. For these use cases a `StateMachine` is
exposing a functional interface `StateMachineAccessor` which provides
an interface to get access to individual `StateMachine` and
`Region` instances.

`StateMachineFunction` is a simple functional interface which allows
to apply `StateMachineAccess` interface into a state machine. With
jdk7 these will create a little verbose code but with jdk8 lambdas
things look relatively non-verbose.

Method `doWithAllRegions` gives access to all `Region` instances in
a state machine.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetZA]
----

Method `doWithRegion` gives access to single `Region` instance in a
state machine.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetZB]
----

Method `withAllRegions` gives access to all `Region` instances in
a state machine.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetZC]
----

Method `withRegion` gives access to single `Region` instance in a
state machine.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetZD]
----

[[sm-interceptor]]
== State Machine Interceptor
Instead of using a `StateMachineListener` interface one option is to
use a `StateMachineInterceptor`. One conceptual difference is that an
interceptor can be used to intercept and stop a current state
change or transition logic. Instead of implementing full interface,
adapter class `StateMachineInterceptorAdapter` can be used to override
default no-op methods.

[NOTE]
====
There is one recipe <<statemachine-recipes-persist>> and one sample
<<statemachine-examples-persist>> which are related to use of an
interceptor.
====

Interceptor can be registered via `StateMachineAccessor`. Concept of
an interceptor is relatively deep internal feature and thus is not
exposed directly via `StateMachine` interface.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetZH]
----

[NOTE]
====
More about error handling shown in above example, see section
<<sm-error-handling>>.
====

[[sm-security]]
== State Machine Security
Security features are build atop of functionality from a _Spring
Security_. Security features are handy when it is required to protect
part of a state machine execution and interaction with it. More
detailed info can be found from section <<sm-security-details>>.

[IMPORTANT]
====
We expect user to be fairly familiar with a _Spring Security_ meaning
we don't go into details of how overall security framework works. For
this read _Spring Security_ reference documentation.
====

[TIP]
====
For complete example, see sample <<statemachine-examples-security>>.
====

=== Configuring Security
All generic configurations for security are done from
`SecurityConfigurer` which is obtained from
`StateMachineConfigurationConfigurer`. Security is disabled on
default even if _Spring Security_ classes are
present.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests3.java[tags=snippetD]
----

If absolutely needed `AccessDecisionManager` for both events and
transitions can be customised. If decision managers are not defined or
are set to `null`, default managers are created internally.

=== Securing Events
Event security is defined on a global level within a
`SecurityConfigurer`.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests3.java[tags=snippetA]
----

In above configuration we use expression `true` which always evaluates
to _TRUE_. Using an expression which always evaluates to _TRUE_
would not make sense in a real application but gives a point that
expression needs to return either _TRUE_ or _FALSE_. We also defined
attribute `ROLE_ANONYMOUS` and `ComparisonType` `ANY`. Using attributes
and expressions, see section <<sm-security-attributes-expressions>>.

=== Securing Transitions
Transition security can be defined globally.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests3.java[tags=snippetF]
----

If security is defined in a transition itself it will override any
globally set security.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests3.java[tags=snippetB]
----

Using attributes and expressions, see section <<sm-security-attributes-expressions>>.

=== Securing Actions
There are no dedicated security definitions for actions in a state
machine, but it can be accomplished using a global method security
from a _Spring Security_. This simply needs that an `Action` is
defined as a proxied `@Bean` and its `execute` method annotated with a
`@Secured`.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests3.java[tags=snippetC]
----

Global method security needs to be enabled with a _Spring Security_
which is done with along a lines shown below. See _Spring Security_
reference docs for more details.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests3.java[tags=snippetE]
----

[[sm-security-attributes-expressions]]
=== Using Security Attributes and Expressions
Generally there are two ways to define security properties, firstly
using security attributes and secondly using security expressions.
Attributes are easier to use but are relatively limited in terms of
functionality. Expressions provide more features but are a little bit
of harder to use.

This section is splitted into different subsections because we're
re-using something from a _Spring Security_ and then do custom
attributes and expression handling for events and transitions.

==== Generic Attribute Usage
On default `AccessDecisionManager` instances for events and
transitions use a `RoleVoter`, meaning you can use role attributes.

For attributes we have 3 different comparison types, `ANY`, `ALL` and
`MAJORITY` which maps into voters `AffirmativeBased`, `UnanimousBased`
and `ConsensusBased` respectively.

==== Generic Expression Usage
Security expressions needs to return either _TRUE_ or _FALSE_.

==== Event Attributes
Event id can be matched by using prefix _EVENT__. For example matching
event `A` would match with attribte _EVENT_A_.

==== Event Expressions
For generic options for expressions, see _Spring Security_ docs. We
inherit from `SecurityExpressionRoot` and options from there are
available.

==== Transition Attributes
Matching transition sources and targets, use prefixes
_TRANSITION_SOURCE__ and  _TRANSITION_TARGET__ respectively.

==== Transition Expressions
For generic options for expressions, see _Spring Security_ docs. We
inherit from `SecurityExpressionRoot` and options from there are
available.

[[sm-security-details]]
=== Understanding Security
This section provides more detailed info how security works within a
state machine. Not really something you'd need to know but it is
always better to be transparent instead of hiding all the magic what
happens behind a scenes.

Security only makes sense if _State Machine_ is executed in a wallet
garden where user don't have direct access to the application thus
could modify Spring Security's `SecurityContext` hold in a thread
local. If user controls the jvm, then effectively there is no security
at all.

Integration point for security is done with a
`StateMachineInterceptor` which is then added automatically into a
state machine if security is enabled. Specific class is a
`StateMachineSecurityInterceptor` which intercepts events and
transitions. This interceptor then consults Spring Security's
`AccessDecisionManager` if event can be send or if transition can be
executed. Effectively if decision or vote with a `AccessDecisionManager`
will result an exception, event or transition is denied.

Due to way how `AccessDecisionManager` from Spring Security works, we
need one instance of it per secured object. This is a reason why there
is a different manager for events and transitions. In this case events
and transitions are different class objects we're securing.

On default for events, voters `EventExpressionVoter`, `EventVoter` and
`RoleVoter` are added into a `AccessDecisionManager`.

On default for transitions, voters `TransitionExpressionVoter`,
`TransitionVoter` and `RoleVoter` are added into a `AccessDecisionManager`.

[[sm-error-handling]]
== State Machine Error Handling
If state machine detects an internal error during a state transition
logic it may throw an exception. Before this exception is processed
internally, user is given a chance to intercept.

Normal `StateMachineInterceptor` can be used to intercept errors and
example of it is shown above.
[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippet1]
----

When errors are detected, normal event notify mechanism is executed.
This allows to use either `StateMachineListener` or Spring Application
context event listener, more about these read section
<<sm-listeners>>.

Having said that, a simple listener would look like:

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippet2]
----

Generic `ApplicationListener` checking `StateMachineEvent` would look
like.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippet3]
----

It's also possible to define `ApplicationListener` directly to
recognize only `StateMachineEvent` instances.

[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippet4]
----

[[sm-persist]]
== Persisting State Machine
Traditionally an instance of a state machine is used as is within a
running program. More dynamic behaviour is possible to achieve via
dynamic builders and factories which allows state machine
instantiation on-demand. Building an instance of a state machine is
relatively heavy operation so if there is a need to i.e. handle
arbitrary state change in a database using a state machine we need to
find a better and faster way to do it.

Persist feature allows user to save a state of a state machine itself
into an external repository and later reset a state machine based of
serialized state. For example if you have a database table keeping
orders it would be way too expensive to update order state via a state
machine if a new instance would need to be build for every change.
Persist feature allows you to reset a state machine state without
instantiating a new state machine instance.

[NOTE]
====
There is one recipe <<statemachine-recipes-persist>> and one sample
<<statemachine-examples-persist>> which provides more info about
persisting states.
====

While it is possible to build a custom persistence feature using a
`StateMachineListener` it has one conceptual problem. When listener
notifies a change of state, state change has already happened. If a
custom persistent method within a listener fails to update serialized
state in an external repository, state in a state machine and state in
an external repository are then in inconsistent state.

State machine interceptor can be used instead of where attempt to save
serialized state into an external storage is done during the a state
change within a state machine. If this interceptor callback fails,
state change attempt will be halted and instead of ending into an
inconsistent state, user can then handle this error manually. Using
the interceptors are discussed in <<sm-interceptor>>.

[[sm-distributed]]
== Using Distributed States
Distributed state is probably one of a most compicated concepts of a
Spring State Machine. What exactly is a distributed state? A state
within a single state machine is naturally really simple to understand
but when there is a need to introduce a shared distributed state
through a state machines, things will get a little complicated.

[NOTE]
====
Distributed state functionality is still a preview feature and is not
yet considered to be stable in this particular release. We expect this
feature to mature towards the first official release.
====

For generic configuration support see section
<<statemachine-config-commonsettings>> and actual usage example see
sample <<statemachine-examples-zookeeper>>.

`Distributed State Machine` is implemented via a
`DistributedStateMachine` class which simply wraps an actual instance
of a `StateMachine`. `DistributedStateMachine` intercepts
communication with a `StateMachine` instance and works with
distributed state abstractions handled via interface
`StateMachineEnsemble`. Depending on an actual implementation
`StateMachinePersist` interface may also be used to serialize a
`StateMachineContext` which contains enough information to reset a
`StateMachine`.

While `Distributed State Machine` is implemented via an abstraction,
only one implementation currently exists based on `Zookeeper`.

Here is a generic example of how `Zookeeper` based `Distributed State
Machine` would be configured.

[source,java,indent=0]
----
include::samples/DocsZookeeperSampleTests.java[tags=snippetA]
----

Current technical documentation of a `Zookeeker` based distributed
state machine can be found from an appendice <<appendices-zookeeper>>.

=== ZookeeperStateMachineEnsemble
`ZookeeperStateMachineEnsemble` itself needs two mandatory settings,
an instance of `curatorClient` and `basePath`. Client is a
`CuratorFramework` and path is root of a tree in a `Zookeeper`.

Optionally it is possible to set `cleanState` which defaults to `TRUE`
and will clear existing data if no members exists in an ensemble. Set
this to `FALSE` if you want to preserve distributed state within
application restarts.

Optionally it is possible to set a size of a `logSize` which defaults
to `32` and is used to keep history of state changes. Value of this
setting needs to be a power of two. `32` is generally good default
value but if a particular state machine is left behind more than a
size of a log it is put into error state and disconnected from an
ensemble indicating it has lost its history to reconstruct fully
synchronized status.

[[sm-test]]
== Testing Support
We have also added a set of utility classes to easy testing of a state
machine instances. These are used in a framework itself but are also
very useful for end users.

`StateMachineTestPlanBuilder` is used to build a `StateMachineTestPlan`
which then have one method `test()` which runs a plan.
`StateMachineTestPlanBuilder` contains a fluent builder api to add
steps into a plan and during these steps you can send events and check
various conditions like state changes, transitions and extended state
variables.

Let's take a simple `StateMachine` build using below example:

[source,java,indent=0]
----
include::samples/DocsTestSampleTests.java[tags=snippetB]
----

In below test plan we have two steps, first we check that initial
state `S1` is indeed set, secondly we send an event `E1` and expect
one state change to happen and machine to end up into a state `S1`.

[source,java,indent=0]
----
include::samples/DocsTestSampleTests.java[tags=snippetA]
----

These utilities are also used within a framework to test distributed
state machine features and multiple machines can be added to a plan.
If multiple machines are added then it is also possible to choose if
event is sent to particular, random or all machines.
