spring-projects / spring-statemachine

Spring Statemachine is a framework for application developers to use state machine concepts with Spring.
1.54k stars 605 forks source link

Imported uml state machines do not work in spring state machine #888

Closed nyemiks closed 3 years ago

nyemiks commented 3 years ago

I have observed a strange behaviour when loading a spring statemachine configured via uml. If the state machine has a sub machine state that references a state machine. The parent state machine only works if the referenced sub machine was created as a sub machine under the parent state machine. i.e. if I import a new state machine using papyrus. Then I reference the imported state machine as a sub machine state. When running the program the state that holds a reference to the imported state machine is not a created as a sub state.

However if i create a new state machine under the parent state machine and reference it as specified in the current spring state machine documentation it works fine.

https://docs.spring.io/autorepo/docs/spring-statemachine/1.2.x-SNAPSHOT/reference/html/sm-papyrus.html

My conclusion is that Imported state machines do not work in spring state machine project.

Please if there is a way to make this work I would appreciate assistance.

My requirements are such that I can use state machines configured by other modellers on my team. Each model created by a team member can be in it's own package. e.g. org.mycompany.finance. sm. or org.mycompany.telecom.sm. The only way this can be done effectively is to import the models based on the two approaches explained here in the papyrus modelling video.

https://www.youtube.com/watch?v=l7c1HORYyX8

It appears Spring statemachine does not yet support the ability to import state machine models.

mehmetsalgar commented 3 years ago

First of let me tell you this, I have no organic connection to the Spring Statemachine Project but I am using Papyrus and Spring State Machine in lots of project....

The bad news the implementation of using Eclipse Papyrus Diagram in Spring Statemachine is really limited, specially complex projects like many enterprise projects and my observation SSM Project does not have enough men power to develop this feature completely.

And yes I know the problem you mentioned, I suffered in some cases and while I can't wait the solution from SSM project, I implemented my way, which is generating Java Configuration Beans for Spring State Machine from UML Diagrams via Eclipse XText and XPand frameworks....

Spring State Machine is capable of doing what you want but not with its own Papyrus Module....

I have two blog entries, one explains how can you generate Spring State Machine configuration from a Papyrus Model via Eclipse XPand (but I have to tell XPand is older then XTend and not so well supported as Xtend) and another version is creating you DSL via XText and generating Spring State Machine configuration from your DSL.

In my projects, I also generate Spring State Machine configuration mit XTend directly from Papyrus UML Diagrams but I didn't have time to publish that as Blog, and I don't know when I can do that because my workload, but it is also possible (you will have less stress with eclipse dependencies while XTend is more up to date)..

If you want to use the full power of the Papyrus UML, I am sry but most probably you will have to generate Java Configuration Beans for Spring State Machine yourself...

Please check the blog entries, may be it will help you....

XPand Version

XText Version

jvalkeal commented 3 years ago

I played with this type a model and it should not be that much of a work to get it working as a supported case

image

Content looks something like:

<?xml version="1.0" encoding="UTF-8"?>
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_9FX-oDIkEeuiF9TAc5z9jA" name="import-main">
  <packageImport xmi:type="uml:PackageImport" xmi:id="_9FxAMDIkEeuiF9TAc5z9jA">
    <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
  </packageImport>
  <packagedElement xmi:type="uml:StateMachine" xmi:id="_9FbpADIkEeuiF9TAc5z9jA" name="StateMachineMain">
    <region xmi:type="uml:Region" xmi:id="_9FcQEDIkEeuiF9TAc5z9jA" name="Region1">
      <transition xmi:type="uml:Transition" xmi:id="_ZIlxwDIlEeuiF9TAc5z9jA" source="_XaQnsDIlEeuiF9TAc5z9jA" target="_T92yQDIlEeuiF9TAc5z9jA"/>
      <transition xmi:type="uml:Transition" xmi:id="_aPiLsDIlEeuiF9TAc5z9jA" source="_T92yQDIlEeuiF9TAc5z9jA" target="_VoLmEDIlEeuiF9TAc5z9jA"/>
      <subvertex xmi:type="uml:State" xmi:id="_T92yQDIlEeuiF9TAc5z9jA" name="MAIN1"/>
      <subvertex xmi:type="uml:State" xmi:id="_VoLmEDIlEeuiF9TAc5z9jA" name="MAIN2">
        <submachine xmi:type="uml:StateMachine" href="../import-sub/import-sub.uml#_FylmYDIlEeuiF9TAc5z9jA"/>
      </subvertex>
      <subvertex xmi:type="uml:Pseudostate" xmi:id="_XaQnsDIlEeuiF9TAc5z9jA" name=""/>
    </region>
  </packagedElement>
</uml:Model>
<?xml version="1.0" encoding="UTF-8"?>
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_FyeRoDIlEeuiF9TAc5z9jA" name="import-sub">
  <packageImport xmi:type="uml:PackageImport" xmi:id="_FzAdIDIlEeuiF9TAc5z9jA">
    <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
  </packageImport>
  <packagedElement xmi:type="uml:StateMachine" xmi:id="_FylmYDIlEeuiF9TAc5z9jA" name="StateMachineSub">
    <submachineState xmi:type="uml:State" href="../import-main/import-main.uml#_VoLmEDIlEeuiF9TAc5z9jA"/>
    <region xmi:type="uml:Region" xmi:id="_FymNcDIlEeuiF9TAc5z9jA" name="Region1">
      <transition xmi:type="uml:Transition" xmi:id="_RQ5cwDIlEeuiF9TAc5z9jA" source="_PKslQDIlEeuiF9TAc5z9jA" target="_IqvfQDIlEeuiF9TAc5z9jA"/>
      <transition xmi:type="uml:Transition" xmi:id="_SNtDQDIlEeuiF9TAc5z9jA" source="_IqvfQDIlEeuiF9TAc5z9jA" target="_LtkXEDIlEeuiF9TAc5z9jA"/>
      <subvertex xmi:type="uml:State" xmi:id="_IqvfQDIlEeuiF9TAc5z9jA" name="CHILD1"/>
      <subvertex xmi:type="uml:State" xmi:id="_LtkXEDIlEeuiF9TAc5z9jA" name="CHILD2"/>
      <subvertex xmi:type="uml:Pseudostate" xmi:id="_PKslQDIlEeuiF9TAc5z9jA" name=""/>
    </region>
  </packagedElement>
</uml:Model>
  1. Looks like when iterating through uml structure I'll get same nodes twice on some cases. Might be a way I do the iteration but looks like if I just track what's been seen(states/trasitions, etc) it works.

  2. In case of a uml resource is resolved from a classpath(it's not a physical file) we've copied that out into a disk and point eclipse classes to parse from there. It looks like when importing theres ref like href="../import-main/import-main.uml#_VoLmEDIlEeuiF9TAc5z9jA" so we'd need to provide user a some sort of hooks add these additional files. I think relative links should be doable but I'm not sure if papyrus can add OS dependant paths to those links.

jvalkeal commented 3 years ago

Now in 2.2.x and ported to 2.3.x, 2.4.x and main.

nyemiks commented 3 years ago

Thanks Janne. I am currently using version 2.2.0 release.

When will 2.2.2.RELEASE be available ?

Do I have to wait till then before accessing this fix ?

nyemiks commented 3 years ago

Sorry for the rather late feedback.

Thank you for your response. I will go through the links you shared.

However I can now see that Janne has worked on the issue. It is now closed. I will test it and revert if there are any issues.

On Mon, 26 Oct 2020, 08:32 mehmetsalgar, notifications@github.com wrote:

First of let me tell you this, I have no organic connection to the Spring Statemachine Project but I am using Papyrus and Spring State Machine in lots of project....

The bad news the implementation of using Eclipse Papyrus Diagram in Spring Statemachine is really limited, specially complex projects like many interprise projects and my observation Projecz does not have enough men power to develop this feature completely.

And yes I know the problem you mentioned, I suffered in some cases and while I can't wait the solution from Spring State Machine project, I implemented my way, which is generating Java Configuration Beans for Spring State Machine from UML Diagrams via Eclipse XText and XPand frameworks....

Spring State Machine is capable of doing what you want but not with its own Papyrus Module....

I have two blog entries, one explains how can you generate Spring State Machine configuration from a Papyrus Model via Eclipse XPand (but I have to tell XPand is older then XTend and not so well supported as Xtend) and another version is creating you DSL via XText and generating Spring State Machine configuration from your DSL.

In my projects, I also generate Spring State Machine configuration mit XTend directly from Papyrus UML Diagrams but I didn't have time to publish that as Blog, and I don't know when I can do that because my workload, but it is also possible (you will have less stress with eclipse dependencies while XTend is more up to date)..

If you want to use the full power of the Papyrus UML, I am sry but most probably you will have to generate Java Configuration Beans for Spring State Machine yourself...

Please check the blog entries, may be it will help you....

XPand Version https://mehmetsalgar.wordpress.com/2015/12/14/ajax-spring-web-flow-and-spring-state-machine/

XText Version https://mehmetsalgar.wordpress.com/2016/01/20/xtext-domain-specific-language-and-spring-state-machine/

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/spring-projects/spring-statemachine/issues/888#issuecomment-716365395, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFJULMP2IUBMFTSFWPCTTV3SMUQ2FANCNFSM4S6U6SNQ .

jvalkeal commented 3 years ago

@nyemiks Well I can release 2.2.2 anytime, but it would be good if you could try snapshots as I would not be surprised if something goes wrong with your use cases. Things are kinda complex with these particular uml models.

jvalkeal commented 3 years ago

But having said that, if/when things go south then it'd be a good to see real uml model structures. If there's something you can't share publicly you can always drop me an email. It's really those cross-links where thing might go wrong as I'm not sure how papyrus can do linking in a various cases(as papyrus probably does it within eclipse bubble, possibly on a OS dependant way).

nyemiks commented 3 years ago

@nyemiks Well I can release 2.2.2 anytime, but it would be good if you could try snapshots as I would not be surprised if something goes wrong with your use cases. Things are kinda complex with these particular uml models.

How can I access the 2.2.2.SNAPSHOT ? What changes do I need to do to my pom.xml ?

nyemiks commented 3 years ago

But having said that, if/when things go south then it'd be a good to see real uml model structures. If there's something you can't share publicly you can always drop me an email. It's really those cross-links where thing might go wrong as I'm not sure how papyrus can do linking in a various cases(as papyrus probably does it within eclipse bubble, possibly on a OS dependant way).

My intended use for imported state machine is as follows:

I created a state machine called ContactBTF3. This machine was defined in the package "com.zkspring.demo.uml.btf.contact

"

image

This machine can call another machine called "EditContactBTF". EditContactBTF which is defined in it's own package "com.zkspring.demo.uml.btf.contact.edit"

From the attached screenshot editContactBTF was imported into ContactBTF3

image

Note: my intention for now is to be able to re use state machines defined in the same project. I just want them in different packages. The reason for this is that different developers can work on their own state machine. However, It will be nice if state machines from another eclipse project can be imported as well. This will encourage re use. We will definitely want to be able to do this eventually.

I have tested the attached configuration using 2.2.0.RELEASE and 2.2.1.RELEASE. whenever I call statemachine..sendEvent( event ); the response is false. Implying that the event did not fire.

However If I nest EditContactBTF as a sub machine in ContactBTF3 it works fine. See below

image

But doing this goes against my intention to re use state machines defined by other developers.

Kindly share how I can access the 2.2.2 snapshot so I can test it as well.

jvalkeal commented 3 years ago

You need to add spring snapshot repo https://repo.spring.io/snapshot to your maven/gradle config and then use version 2.2.2.BUILD-SNAPSHOT.

nyemiks commented 3 years ago

I have been access the snapshot. Thank you. I have tested it. It does not work. No errors are generated.

whenever I call statemachine..sendEvent( event );

The response value is false implying that the event did not fire.

jvalkeal commented 3 years ago

Try to create an example showing your issue. Use something like https://github.com/jvalkeal/randomstuff/tree/master/ssm-sample4 as a skeleton project. That's a sample I used to play with these imports.

nyemiks commented 3 years ago

Okay I will proceed to create a similar project.

However, I have studied the sample project you shared now I have noticed two main differences:

  1. You placed all the state machines in the src/main/resources folder. I placed mine in the src/main/java.

  2. In your project I noticed that you referenced the two state machines uml files when building the UMLStateMachineModelFactory. In my own project I am only referencing one. i.e. the parent.

I will work on your example and revert.

nyemiks commented 3 years ago

I have studied your example. I have implemented the two changes I observed. It works fine now.

The issue was that I was not referencing the imported state machine. This is mandatory.

Placing the uml's in src/main/java also works. I prefer this approach because I am using papyrus uml. The papyrus visual designer does not seem to work when the uml files are placed in the src/main/resources folder. So for developers who are fine working with the uml editor directly (i.e. no papyrus visual designer) then it's okay to place your models in src/main/resources folder.

Thanks.

jvalkeal commented 3 years ago

Yeah, it doesn't matter if under java or resources if things end up in a classpath. Reason for a need to define those additional files was mentioned in docs/pr as I haven't found a way for eclipse libs to be able to read from a classpath so things needs to be temporarily copied into a file system.