Petri Net Sagas ¶
The Saga pattern offers an availability-oriented alternative to classic distributed transaction and locking mechanisms. Use cases are large systems, that use the shared-nothing data model, which is typically fulfilled by microservice applications. Sagas are traditionally defined by a sequence of local transactions, but often concurrency between transactions is possible.
This website presents a solution to model concurrent Sagas with P/T workflow nets, called Petri net Sagas. As a proof-of-concept an implementation shows, how to translate Petri net Sagas to reference nets and to execute them using the Renew simulation core. The implementation is available as a library for the Java programming language.
In addition to the general Petri net Saga Framework an adapter for the Eventuate Tram Saga framework is available.
For a quick startup instruction on the example please refer to our video instruction and/or follow the instructions below.
Download ¶
Example project (BookStoreSaga): Download
Download to see Petri net Sagas in action! Please refer to the setup insctructions below to set it up. Based on Spring Boot, Petri net Sagas and the Eventuate Tram framework adapter.
Empty starter project: Download
Use this project to build your own example from scratch. Prepared with Spring Boot, Petri net Sagas and the Eventuate Tram Sagas framework.
Library files + Eventuate Tram adapter only: Download
For experienced users. These are just the library files for Petri net Sagas and the Eventuate Tram Adapter. These can be combined with other projects, e.g. non-Spring-based.
Setup instructions for the example ¶
General information ¶
The setup assumes a Linux environment. If you work under macOS or Windows details might differ from the here presented instructions. It is highly recommended to prepare a local installation of Docker and docker-compose, as it greatly eases setup of the required service components for the microservice infrastructure. It is, however, not necessary to do so on the same machine, that the (sample) code is to be run. So it is possible to run the Docker based services on one machine and the code on another. Note, that under Windows Docker needs to run in Linux-image compatible mode, as some key images are only available for the Linux platform.
A working Java JDK (e.g. OpenJDK) needs to be present with support for at least Java 11!
The utility curl
is also recommended to test things out.
The deployment requires a microservice environment (that can be supplied by just one machine for testing purposes) with the following applications:
If you do not use the Docker-based setup please refer to the respective projects websites on information on how to set these up.
Steps ¶
Download the Example package (BookStoreExample.zip) (see above) and unzip it.
To set up all the dependencies it is sufficient to navigate to the folder "docker" and issue the command docker-compose up -d
from within that directory.
If you have installed docker on another machine, make sure direct connection between your machine and the docker machine is possible, and ports 2181
, 9092
, 3306
, 8099
and 9411
are not firewalled.
Please also make sure, that the host running the docker containers does not use the ports 2181
, 9092
, 3306
, 8099
or 9411
.
Otherwise the docker startup will fail, because it cannot bind the ports.
Depending on your local setup you might need to supply elevated permissions (e.g. by using sudo
) to the docker-compose command.
The service infrastructure can be tore down again with the command docker-compose down
from within the same directory.
If you are running docker on another machine you need to tell the sample application the IP docker and the services are running on.
Do so by setting the environment variable DOCKER_HOST_IP
. E.g. by executing: set DOCKER_HOST_IP=www.xxx.yyy.zzz
or DOCKER_HOST_IP=www.xxx.yyy.zzz
depending on your shell.
If you run docker on the same machine, you do not need to do this.
To build the sample application navigate to the main directory and run ./gradlew build
.
The build process will attempt to reach the running services, so a BUILD FAILED
most likely indicates, that the services could not be reached under the IP specified.
After successful compilation, the application can be run by executing ./gradlew bootrun
.
Once the application hast started successfully the log shows the line Started BookStoreExampleApplication in xxxx seconds (JVM running for xxxx)
The system will load the Petri net Saga Definition from the local file "BookOrderSaga.pnml".
Open up a second terminal and run the command curl -X POST localhost:8080/order?creditCardLimit=500
This will issue the order to run a Saga in the system.
The system generates a random book price and tries to order it from the (cent) limit supplied by the call (500 cents).