This is a lightweight and extensible framework for asynchronous and synchronous process composition. Initially started and used as a sub-module of Hive2Hive, an open-source Java library for secure, distributed, P2P-based file synchronization and sharing, this framework now is a standalone module that might be helpful for your projects, too. It's licensed under the MIT License and any contribution is welcome.
Features
API Demonstration
Architecture
Installation
Documentation
Contribution
Contact
- simple, straightforward API
- supports:
- rollback
- result computation
- pause/resume
- asynchronous execution/rollback
- easily extendable due to the use of GoF Design Patterns:
- all components have the same API
- processes can be built by using a Composite:
- use default containers or define your own
- define your own process steps
- process trees can be built by nesting components (containers, steps)
- processes can be extended by adding behaviour/state by using a Decorator:
- use default decorators or define your own
The following code shows the most fundamental things that can be done with the framework.
Creating a ProcessStep
Simply inherit from the abstract class ProcessStep<T>
, where T
is the type of the result, and implement doExecute()
(and doRollback()
). (Tip: T
can also be Void
.)
public class MyProcessStep extends ProcessStep<Integer> {
@Override
protected Integer doExecute() throws InvalidProcessStateException, ProcessExecutionException {
// do some stuff...
int result = 1 + 2 + 3;
// tag for rollback
setRequiresRollback(true);
return result;
}
@Override
protected Integer doRollback() throws InvalidProcessStateException, ProcessRollbackException {
// rollback stuff...
int result = 0;
// untag for rollback
setRequiresRollback(false);
return result;
}
}
Execution and Rollback
Then, the above created step can be executed and its result retrieved as follows. In case of an execution error, it could directly be rolled back.
ProcessStep<Integer> step1 = new MyProcessStep();
int result;
try {
result = step1.execute();
} catch (ProcessExecutionException ex) {
result = step1.rollback();
}
Asynchronous Components
Every IProcessComponent<T>
can be wrapped with the AsyncComponent
decorator. With this, the component's execution and rollback run on a separate thread and immediately return control to the caller.
ProcessStep<Integer> step2 = new MyProcessStep();
IProcessComponent<Future<Integer>> asyncStep2 = new AsyncComponent<Integer>(step2);
Future<Integer> futureResult = asyncStep2.execute();
Note: Dealing with asynchronous components might be a bit tricky. Make sure to take a look at our Wiki Example to be sure to use it correctly.
Process Composition
Classes inheriting from ProcessComposition<T>
allow to nest IProcessComponent
s and to build process trees. The below example shows the usage of the default SyncProcess
.
ProcessComposite<Void> composite1 = new SyncProcess();
ProcessComposite<Void> composite2 = new SyncProcess();
composite1.add(step1); // add a single ProcessStep
composite1.add(asyncStep2); // add an async component
composite1.add(composite2); // add another ProcessComposite
Now, we could make the whole composite run asynchronously.
IProcessComponent<Future<Void>> asyncComposite = new AsyncComponent<Void>(composite1);
try {
// execute composite sync
composite.execute();
// or async
asyncComposite.execute();
} catch (ProcessExecutionException ex) {
// rollback composite sync
composite.execute();
// or async
asyncComposite.rollback();
}
Pause and Resume
IProcessComponent<T>
s that are wrapped with the AsyncComponent
decorator can be paused/resumed because they run asynchronously.
asyncComposite.execute();
asyncComposite.pause();
// do other stuff meanwhile...
asyncComposite.resume();
The most essential elements are the following:
IProcessComponent<T>
: Basic interface for all process components. Defines all common functionality.T
is the type of the result computed by thisIProcessComponent
.ProcessComponent<T>
: Abstract base class for all process components. Keeps track of a process components' most essential properties and functionalities.ProcessStep<T>
: Abstract base class for all normalIProcessComponent
s (leaf). These normal components represent a specific operation and do not contain otherIProcessComponent
s.ProcessComposite<T>
: Abstract base class for all compositeIProcessComponent
s. These composites contain otherIProcessComponent
s.ProcessDecorator<T>
: Abstract base class for all decorators that decorateIProcessComponent
s. These decorators provide additional behavior or state to existing implementations ofIProcessComponent
s.
The graphic depicts the state transitions that are valid for all IProcessComponent
s. In case some component tries to enter an invalid state, an InvalidProcessStateException
will be thrown.
There are three easy ways to get and include the Hive2Hive Process Framework into your project.
If you just want to use the framework, either refer to option 1 or 2.
If you want to contribute to the project, please refer to option 3.
- Option 1: Add Maven dependency (recommended)
You can add the latest stable release as an Apache Maven dependency. Add the following to yourpom.xml
and make sure to select the most recent version.
<dependency>
<groupId>org.hive2hive</groupId>
<artifactId>org.hive2hive.processframework</artifactId>
<version>1.X</version>
</dependency>
- Option 2: Add JAR-file directly
In case you don't want to use Maven, you can just download the latest stable release. The required.jar
-files is packed and delivered to you as a.zip
. - Option 3: Clone from GitHub
If you want to contribute to the Hive2Hive ProcessFramework project, this is what you should do. Cloning from thedev
branch allows yout to get the bleeding edge of development. This option is not recommended if you just want to use the library.
- This
README.md
file should contain the most essential documentation necessary to start with the project. - There is an additional documentation on our Hive2Hive GitHub Wiki.
- The source code itself is thoroughly documented using JavaDoc.
- In case you still have unanswered questions, don't hesitate to contact us!
For more details and documentation about the Hive2Hive project, please visit http://www.hive2hive.com/.
The library is intended to be improved and extended so that we all profit from its capabilities. For more information, please refer to our main project.
If you have any questions, feel uncomfortable or uncertain about an issue or your changes, feel free to reach us via email at [email protected]. Please consider posting your question on StackOverflow (using the hive2hive
tag) in case it is a technical question that might interest other developers, too.
We provide you with all information you need and will happily help you via email, Skype, remote pairing or whatever you are comfortable with.