Add docs for repository config
- Docs for base usage, jpa and jpa sample. - Relates to #238
This commit is contained in:
@@ -375,6 +375,7 @@ configure(rootProject) {
|
||||
from 'spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/docs'
|
||||
from 'spring-statemachine-uml/src/test/java/org/springframework/statemachine/uml/docs'
|
||||
from 'spring-statemachine-uml/src/test/resources/org/springframework/statemachine/uml/docs'
|
||||
from 'spring-statemachine-data/jpa/src/test/java/org/springframework/statemachine/data/jpa/docs'
|
||||
from 'spring-statemachine-samples/src/main/java/'
|
||||
from 'spring-statemachine-samples/washer/src/main/java/'
|
||||
from 'spring-statemachine-samples/tasks/src/main/java/'
|
||||
@@ -385,8 +386,11 @@ configure(rootProject) {
|
||||
from 'spring-statemachine-samples/zookeeper/src/main/java/'
|
||||
from 'spring-statemachine-samples/security/src/main/java/'
|
||||
from 'spring-statemachine-samples/eventservice/src/main/java/'
|
||||
from 'spring-statemachine-samples/datajpa/src/main/java/'
|
||||
from 'spring-statemachine-samples/datajpa/src/main/resources/'
|
||||
include '**/*.java'
|
||||
include '**/*.uml'
|
||||
include '**/*.json'
|
||||
into 'docs/src/reference/asciidoc/samples'
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ dependencies outside of Spring Framework within its core system.
|
||||
Other optional parts like <<sm-distributed>> has dependencies to
|
||||
a `Zookeeper`, while <<statemachine-examples>> has dependencies
|
||||
to spring-shell and spring-boot which pulls other dependencies
|
||||
beyond framework itself.
|
||||
beyond framework itself. Also optional security and data access has
|
||||
dependencies to _Spring Security_ and _Spring Data Modules_.
|
||||
|
||||
== Modules
|
||||
The following modules are available for Spring Statemachine.
|
||||
@@ -37,6 +38,12 @@ framework.
|
||||
|spring-statemachine-redis
|
||||
|`Redis` related features for state machine.
|
||||
|
||||
|spring-statemachine-data-common
|
||||
|Common support module for `Spring Data`.
|
||||
|
||||
|spring-statemachine-data-jpa
|
||||
|Support module for `Spring Data JPA`.
|
||||
|
||||
|spring-statemachine-zookeeper
|
||||
|`Zookeeper` integration for a distributed state machine.
|
||||
|
||||
@@ -47,7 +54,7 @@ framework.
|
||||
|Support module for Spring Cloud Cluster.
|
||||
|
||||
|spring-statemachine-uml
|
||||
|Support module for UI uml modeling.
|
||||
|Support module for UI uml modeling with Eclipse Papyrus.
|
||||
|===
|
||||
|
||||
== Using Gradle
|
||||
|
||||
BIN
docs/src/reference/asciidoc/images/sm-datajpa-1.png
Normal file
BIN
docs/src/reference/asciidoc/images/sm-datajpa-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
docs/src/reference/asciidoc/images/sm-datajpa-2.png
Normal file
BIN
docs/src/reference/asciidoc/images/sm-datajpa-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
BIN
docs/src/reference/asciidoc/images/sm-datajpa-3.png
Normal file
BIN
docs/src/reference/asciidoc/images/sm-datajpa-3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
29
docs/src/reference/asciidoc/samples/data.json
Normal file
29
docs/src/reference/asciidoc/samples/data.json
Normal file
@@ -0,0 +1,29 @@
|
||||
[
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
|
||||
"initial": true,
|
||||
"state": "S1"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S2"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S3"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
|
||||
"source": "S1",
|
||||
"target": "S2",
|
||||
"event": "E1"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
|
||||
"source": "S2",
|
||||
"target": "S3",
|
||||
"event": "E2"
|
||||
}
|
||||
]
|
||||
@@ -36,6 +36,8 @@ normal build cycle. Samples in this chapter are:
|
||||
|
||||
<<statemachine-examples-ordershipping>> Order Shipping.
|
||||
|
||||
<<statemachine-examples-datajpa>> JPA Config.
|
||||
|
||||
|
||||
[source,text]
|
||||
----
|
||||
@@ -1425,3 +1427,69 @@ Finally you can see what machine does by refressing a page.
|
||||
|
||||
image::images/sm-ordershipping-4.png[width=1000]
|
||||
|
||||
[[statemachine-examples-datajpa]]
|
||||
== JPA Config
|
||||
JPA Config is an example how state machine concepts can be used
|
||||
with a machine configuration kept in a database. This sample is using
|
||||
embedded _H2_ database with a _H2 Console_ to ease playing with a
|
||||
database.
|
||||
|
||||
To enable automatic scan of needed _Entity_ classes and _JPA
|
||||
Repositories_, a boot application can be annotated with a custom
|
||||
locations as shown below.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::samples/demo/datajpa/Application.java[tags=snippetA]
|
||||
----
|
||||
|
||||
What comes for a machine config `RepositoryStateMachineModelFactory`
|
||||
can be used as shown below.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::samples/demo/datajpa/StateMachineConfig.java[tags=snippetB]
|
||||
----
|
||||
|
||||
Lets get into actual demo. Run the boot based sample application:
|
||||
|
||||
[source,text,subs="attributes"]
|
||||
----
|
||||
# java -jar spring-statemachine-samples-datajpa-{revnumber}.jar
|
||||
----
|
||||
|
||||
Accessing application via _http://localhost:8080_ brings up a new
|
||||
constructed machine with every request and you can choose to send
|
||||
events to a machine. Possible events and machine configuration are
|
||||
updated from a database with every request.
|
||||
|
||||
image::images/sm-datajpa-1.png[width=1000]
|
||||
|
||||
To access embedded console use _JDBC URL_ `jdbc:h2:mem:testdb` if it's
|
||||
not already set.
|
||||
|
||||
image::images/sm-datajpa-2.png[width=1000]
|
||||
|
||||
From console you can see how database tables look like and modify
|
||||
those as you wish.
|
||||
|
||||
image::images/sm-datajpa-3.png[width=1000]
|
||||
|
||||
Now that you got this far you probably wondered how those default
|
||||
states and transitions got populated into a database. Spring Data
|
||||
already have a nice trick to auto populate repositories and we simply
|
||||
use this feature via `Jackson2RepositoryPopulatorFactoryBean`.
|
||||
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::samples/demo/datajpa/StateMachineConfig.java[tags=snippetA]
|
||||
----
|
||||
|
||||
Actual source for populator data is shown below.
|
||||
|
||||
[source,json,indent=0]
|
||||
----
|
||||
include::samples/data.json[]
|
||||
----
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ that Spring Statemachine provides to any Spring based application.
|
||||
|
||||
<<sm-papyrus>> the state machine uml modeling support.
|
||||
|
||||
<<sm-repository>> the state machine repository config support.
|
||||
|
||||
[[sm-config]]
|
||||
== Statemachine Configuration
|
||||
One of the common tasks when using a Statemachine is to design its
|
||||
@@ -2015,3 +2017,57 @@ sub-state.
|
||||
|
||||
image::images/papyrus-gs-15.png[width=400]
|
||||
|
||||
[[sm-repository]]
|
||||
== Repository Config Support
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
Repository abstraction support is still work in progress and scheduled
|
||||
to be complete in future milestones.
|
||||
====
|
||||
|
||||
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` and `TransitionRepository`
|
||||
accompanied with base entity interfaces `RepositoryState` and
|
||||
`RepositoryTransition` 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_, _Mongo_ 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.
|
||||
|
||||
[[sm-repository-jpa]]
|
||||
=== JPA
|
||||
Currently one repository implementation exists which uses _JPA_ to
|
||||
access configured database.
|
||||
|
||||
Actual _Repository_ implementations for a _JPA_ are
|
||||
`JpaStateRepository` and `JpaTransitionRepository` which are backed by
|
||||
_Entity_ classes `JpaRepositoryState` and `JpaRepositoryTransition`
|
||||
respectively.
|
||||
|
||||
Generic way to update states and transition manually is shown below.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::samples/DocsJpaRepositorySampleTests1.java[tags=snippetA]
|
||||
----
|
||||
|
||||
Complete example can be found from sample
|
||||
<<statemachine-examples-datajpa>>.
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.data.jpa.docs;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.statemachine.data.StateRepository;
|
||||
import org.springframework.statemachine.data.TransitionRepository;
|
||||
import org.springframework.statemachine.data.jpa.JpaRepositoryState;
|
||||
import org.springframework.statemachine.data.jpa.JpaRepositoryTransition;
|
||||
|
||||
public class DocsJpaRepositorySampleTests1 {
|
||||
|
||||
public static class Config1 {
|
||||
// tag::snippetA[]
|
||||
@Autowired
|
||||
StateRepository<JpaRepositoryState> stateRepository;
|
||||
|
||||
@Autowired
|
||||
TransitionRepository<JpaRepositoryTransition> transitionRepository;
|
||||
|
||||
void addConfig() {
|
||||
JpaRepositoryState state1 = new JpaRepositoryState("machine1", "S1", true);
|
||||
stateRepository.save(state1);
|
||||
JpaRepositoryState state2 = new JpaRepositoryState("machine2", "S2", false);
|
||||
stateRepository.save(state2);
|
||||
|
||||
JpaRepositoryTransition transition1 = new JpaRepositoryTransition("machine1", "S1", "S2", "E1");
|
||||
JpaRepositoryTransition transition2 = new JpaRepositoryTransition("machine2", "S3", "S4", "E2");
|
||||
transitionRepository.save(transition1);
|
||||
transitionRepository.save(transition2);
|
||||
}
|
||||
// end::snippetA[]
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.orm.jpa.EntityScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
//tag::snippetA[]
|
||||
@SpringBootApplication
|
||||
@EntityScan(basePackages = {"org.springframework.statemachine.data.jpa"})
|
||||
@EnableJpaRepositories(basePackages = {"org.springframework.statemachine.data.jpa"})
|
||||
@@ -29,3 +30,4 @@ public class Application {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
||||
//end::snippetA[]
|
||||
|
||||
@@ -34,13 +34,16 @@ import org.springframework.statemachine.data.TransitionRepository;
|
||||
@Configuration
|
||||
public class StateMachineConfig {
|
||||
|
||||
//tag::snippetA[]
|
||||
@Bean
|
||||
public Jackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
|
||||
Jackson2RepositoryPopulatorFactoryBean factoryBean = new Jackson2RepositoryPopulatorFactoryBean();
|
||||
factoryBean.setResources(new Resource[]{new ClassPathResource("data.json")});
|
||||
return factoryBean;
|
||||
}
|
||||
//end::snippetA[]
|
||||
|
||||
//tag::snippetB[]
|
||||
@Configuration
|
||||
@EnableStateMachineFactory
|
||||
public static class Config extends StateMachineConfigurerAdapter<String, String> {
|
||||
@@ -63,4 +66,5 @@ public class StateMachineConfig {
|
||||
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
|
||||
}
|
||||
}
|
||||
//end::snippetB[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user