Reputation: 87
I'm trying to construct a state machine from thee follwoing UML model using Papyrus. The entryActions for each of the stage is resgistered using DefaultStateMachineComponentResolver , to resolve to respective EntryAction classes in my spring app. My requirement is
1) From the CS stage the execution should fork to two threads, upon getting the triggering event SUCCESS.
2) In one thread DE1 and TE1 should execute sequentially and in the other thread DE2 and TE2 should execute sequentially
3) Transition to END state should happen only if both the threads execute successfully, ie from TE1 a transition should happen to join state signalled by event SUCCESS and from TE2 a transition should happen to join state signalled by event SUCCESS
4) ie. Transition to END state should happen after the successful execution of the 2 threads.
5) While executing each stage if any tasks fails (tasks are written in EntryAction classes), the state machine should navigate to END state , the signals used being FAILURE, TERMINATED (based on the severity of error occured)
Here is the code I used to buildState machine and trigger execution
Builder<String, String> builder = StateMachineBuilder
.<String, String> builder();
builder.configureConfiguration()
.withConfiguration()
.autoStartup(false)
.listener(listener())
.beanFactory(
this.applicationContext.getAutowireCapableBeanFactory());//.taskExecutor(taskExecutor());
DefaultStateMachineComponentResolver<String, String> resolver = new DefaultStateMachineComponentResolver<>();
resolver.registerAction("startEntryAction", this.startEntryAction);
resolver.registerAction("apEntryAction", this.apEntryAction);
resolver.registerAction("psEntryAction", this.psEntryAction);
//all entry action classed are registered
...
...
UmlStateMachineModelFactory umlStateMachineModelFactory = new UmlStateMachineModelFactory("classpath:model.uml");
umlStateMachineModelFactory.setStateMachineComponentResolver(resolver);
builder.configureModel().withModel().factory(umlStateMachineModelFactory);
StateMachine<String, String> stateMachine = builder.build();
stateMachine.start()
Issues I faced
1) While using taskExecutor the state machine execution was not getting started.
2)After commenting out the taskExecutor the exectuion was triggered and in the console I got the logs from entryAction classes.
3)In each entry action classes I just added the below code to transit to next state, and for logging purpose
@Override
public void execute(StateContext<String, String> paramStateContext) {
LOGGER.debug("Start State entered! ");
paramStateContext.getStateMachine().sendEvent("SUCCESS");
}
4) But the problem is the state TE1 was never entered, after analysing the logs. My requirement was END state should be entered after executing the tasks in TE1EntryAction and TE2EntryAction
Please find below the logs
[![enter image description here][1]][1]19:03:54.963 DEBUG o.i.r.p.a.StartEntryAction - Start State entered!
19:03:55.007 DEBUG o.i.r.p.a.APEntryAction - AP State entered!
19:03:55.007 DEBUG o.i.r.p.a.PSEntryAction - PS State entered!
19:03:55.007 DEBUG o.i.r.p.a.PBEntryAction - PB State entered!
19:03:55.007 DEBUG o.i.r.p.a.CSEntryAction - CS State entered!
19:03:55.007 DEBUG o.i.r.p.a.DE1EntryAction - DE1 State entered!
19:03:55.007 DEBUG o.i.r.p.a.DE2EntryAction - DE2 State entered!
19:03:55.007 DEBUG o.i.r.p.a.TE2EntryAction - TE2 State entered!
19:03:55.023 DEBUG o.i.r.p.a.EndStateEntryAction - END State entered!
Is the problem exists in the UML model I created. if so, how should be the state Diagram look like
Thanks a ton for the help.
Upvotes: 1
Views: 3020
Reputation: 2646
At least your fork/join is wrong as you can't have those without using orthogonal regions.
Source for above is in simple-forkjoin.uml
I'm not sure why papyrus allows you to draw fork/join like that as uml spec clearly states:
Fork Pseudostates serve to split an incoming Transition into two or more Transitions terminating on Vertices in orthogonal Regions of a composite State.
I should probably add model verifier if user is trying to add forks/joins without using regions.
Also I'm not sure what should happen with transition from TE2
to END
if machine is waiting join to happen so I'd try to avoid that.
Upvotes: 0