user6882156
user6882156

Reputation:

spring-statemachine 2.3.1 - How to get a StateMachine from a StateMachineModelFactory?

I'm having the following business case while working with spring-statemachine 2.3.1 in a project:

The state machine is defined with the Papyrus plugin and loaded from an uml file using the UmlStateMachineModelFactory as shown below:

public class MyStateMachineConfig extends StateMachineConfigurerAdapter<String, String>
{
  @Override
  public void configure(StateMachineModelConfigurer<String, String> model) throws Exception
  {
    model.withModel().factory(myStateMachineModelFactory());
  }

  @Bean
  public StateMachineModelFactory<String, String> myStateMachineModelFactory()
  {
    return new UmlStateMachineModelFactory("classpath:my.uml");
  }
  ....

I need to persist the state machine context in a database using JPA. In order to do this, I need to use StateMachinePersister.persist(). This method uses as its first input parameter a StateMachine instance. However, I'm not able to get the StateMachine instance from my StateMachineModelFactory. The class StateMachineFactory has a method named getStateMachine() while the class StateMachineModelFactory doesn't.

I didn't find neither a way to get a StateMachineFactory instance from a StateMachineModelFactory instance. Could anyone please help with some suggestions, ideally examples ? The documentation has different examples of how to do it but none for the case when the state machine is loaded from an UML file.

Kind regards,

Nicolas DUMINIL

Upvotes: 1

Views: 1633

Answers (2)

Mykola Shorobura
Mykola Shorobura

Reputation: 768

Your configuration for StateMachineFactory should look like below

@Configuration
@EnableStateMachineFactory
public static class SsmConfig
        extends EnumStateMachineConfigurerAdapter<States, Events> {

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
            throws Exception {
        states
            .withStates()
                .initial(States.S1)
                .end(States.SF)
                .states(EnumSet.allOf(States.class));
    }

}

And then you can simply inject StateMachineFactory everywhere and just get state machine.

class SomeService {

    @Autowired
    private StateMachineFactory<States, Events> factory;

    void method() {
        StateMachine<States,Events> stateMachine = factory.getStateMachine();
        stateMachine.start();
    }
}

More information can be found here.

Upvotes: 2

hovanessyan
hovanessyan

Reputation: 31433

Your configuration, which extends StateMachineConfigurerAdapter is an "adaptation" or modification of the auto-configured Spring state machine.

In order for your configuration to be picked-up by spring you need to annotate it with @Configuration.

You also have to enable the State Machine auto-configuration, which happens with @EnableStateMachie annotation.

@Configuration
@EnableStateMachine
public class MyStateMachineConfig extends StateMachineConfigurerAdapter<String, String> {

You can refer to the official documentation for more details.

Once this is active, you can inject the StateMachine as a dependency.

Upvotes: 1

Related Questions