It is also possible to keep machine configuration in an external storage where it will be loaded on demand instead of creating a static configuration either using JavaConfig or UML based config. This integration works via Spring Data Repository abstraction.
We have created special StateMachineModelFactory
implementation
called RepositoryStateMachineModelFactory
which is able to use base
repository interfaces StateRepository
, TransitionRepository
,
ActionRepository
and GuardRepository
accompanied with base entity
interfaces RepositoryState
, RepositoryTransition
,
RepositoryAction
and RepositoryGuard
respectively.
Due to way how Entities and Repositories work in a Spring Data,
from a user perspective read access can be fully abstracted as it is
done in RepositoryStateMachineModelFactory
as there is no need to
know what is a real mapped Entity class Repository is working
with. Writing into a Repository is always dependant of using a real
Repository specific Entity class. From machine configuration point
of view we don’t need to know these, meaning we don’t need to know
actual implementation whether that is JPA, Redis or anything else
what Spring Data supports. Using a real Repository related
Entity class comes into play when you manually try to write new
states or transitions into a backed repository.
Actual out of a box implementations are documented in below sections.
Actual Repository implementations for a JPA are
JpaStateRepository
, JpaTransitionRepository
, JpaActionRepository
and JpaGuardRepository
which are backed by
Entity classes JpaRepositoryState
, JpaRepositoryTransition
,
JpaRepositoryAction
and JpaRepositoryGuard
respectively.
Generic way to update states and transition manually is shown below.
@Autowired StateRepository<JpaRepositoryState> stateRepository; @Autowired TransitionRepository<JpaRepositoryTransition> transitionRepository; void addConfig() { JpaRepositoryState state1 = new JpaRepositoryState("machine1", "S1", true); JpaRepositoryState state2 = new JpaRepositoryState("machine2", "S2", false); JpaRepositoryState state3 = new JpaRepositoryState("machine1", "S3", true); JpaRepositoryState state4 = new JpaRepositoryState("machine2", "S4", false); stateRepository.save(state1); stateRepository.save(state2); stateRepository.save(state3); stateRepository.save(state4); JpaRepositoryTransition transition1 = new JpaRepositoryTransition("machine1", state1, state2, "E1"); JpaRepositoryTransition transition2 = new JpaRepositoryTransition("machine2", state3, state4, "E2"); transitionRepository.save(transition1); transitionRepository.save(transition2); }
Complete example can be found from sample Chapter 47, JPA Config. This example is also showing how repository can be pre-populated from existing json file having a definitions for entity classes.
Actual Repository implementations for a Redis are
RedisStateRepository
, RedisTransitionRepository
, RedisActionRepository
and RedisGuardRepository
which are backed by
Entity classes RedisRepositoryState
, RedisRepositoryTransition
,
RedisRepositoryAction
and RedisRepositoryGuard
respectively.