31. Repository Config Support

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.

31.1 JPA

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.

31.2 Redis

Actual Repository implementations for a Redis are RedisStateRepository, RedisTransitionRepository, RedisActionRepository and RedisGuardRepository which are backed by Entity classes RedisRepositoryState, RedisRepositoryTransition, RedisRepositoryAction and RedisRepositoryGuard respectively.