Con:cern Documentation

Aus Wiki

Wechseln zu: Navigation, Suche

Navigation: Home | OSBL Main Page | OSBL Documentation | con:cern Main Page


Inhaltsverzeichnis

Project History

con:cern was conceived during the course of a project in 2002/2003 realized with a conventional workflow system, suffering heavily from it. The effort necessary to overcome a series of problems and restrictions of the engine was far greater than its benefit. This is not an isolated case, as numerous developers and architects have agreed. Rather, we are faced with a conceptional problem, which is ultimately the reason, why workflow technology has not yielded the results originally anticipated.

In 2004, con:cern came into operation as part of two newly developed products of Wilken GmbH:

  • E-Procurement Suite
  • E-Marketing Suite

2006 Wilken has build up a new business division with the idea, to leverage the integration of open source components, that make up the technological fundament of these products for general open source development. The new division was called Solution Services. Its initial achievement was the publication of the Open Source Business Library (OSBL) with con:cern at its heart.

How does it work?

The con:cern approach is totally different from most other process engines. Instead of defining the processing order in a procedural manner, the logical interrelation between activities is modelled. Every activity has a precondition and a postcondition. It is executed as soon as its precondition matches. Afterwards the postcondition is evaluated. The processing order is determined at runtime. By examining an instance, the controller can always tell, what the next step is.


The figure shows a create event wurde erstellt (was created), that produces subjects with the state erstellt ("created"), symbolized by the yellow icon. The activity "genehmigen" ("approve") takes subjects in this state and transforms it to subjects with either state abgelehnt ("refused"): red or genehmigt ("approved"): green. The activity "eintragen" ("register") takes the genehmigt- (green)- ones and makes them eingetragen ("registered"): blue. And so on ...


The resulting processing order is rather trivial in this example. Now if for example genehmigen had an additional precondition, that isn't met and there is no other activity in the whole process, whose precondition is met, the process will stall. Stalled instances can be listed and a remedy can be found on the fly.

The Object oriented Approach to Process Management

As of the object- oriented design principle, every con:cern- Process is directly related to certain object- type. This object, also referred to as the Subject, is loaded from an arbitrary persistent store. Its state is the process- state and as such it is projected by a number of Conditions into a logical feature space. Its behaviour is defined as a set of Activities with preconditions and postconditions, that operate on the logical feature space. An activity can be compared with a rule, the process with a rule- set in a rule- engine. In another anology, the conditions can be compared with boolean getters and the activities with methods of the subject. Activities come in two flavours: synchronous and asynchronous. Synchronous Activities perform calculations, call services, send events and the like. Asynchronous Activities accept messages, are triggered by external systems or they are performed by a user. User- Activities can be marked optional. Dependent on this flag, Options or Tasks will be created if the precondition matches. Options are activities for which the assignee might choose to execute it or he might not. Both are assigned to individual users by the associated Actor. Similar to activities are the Events and Listeners. The former have no precondition, the later have no postcondition. And finally there is a notion of equations between conditions, the Expansion and the Conclusion.

Logical versus procedural notion

Notion
Notion

The notion of con:cern is a logical one. The process model does not define the order in which activities take place, but rather identifies their logical dependencies, that may in turn force a certain order of execution. The following figure exemplifies this important difference:

We can conclude, that the con:cern- model contains more information. The special notion and the fact, that additional information is contained in the model, has several advantages:

  • All degrees of freedom in the execution order are conserved, thus it allows for the optimal utilization of resources.
  • A stopped process can be relaunched at any time. The engine will proceed at the correct point.
  • The process flow can be influenced by manipulating the subject.
  • Process instances can simply be migrated to new versions of the process model.
  • Activities can be tested and validated one by one.
  • The approach forces the indeepth elaboration of the requirements.
  • Complex process scenarios are break down into small managable pieces.

The Controller

Every process model is interpreded by a dedicated Controller instance. The controller provides an interface to the application for creating, destroying, suspending and resuming subjects and for querying the log and the current state. The interface can be exposed as an JMX MBean. Methods handling concrete process instances have sting userValue as a parameter. This is the business id of a process instance - org.concern.controller.Subject. In default Controller implementation it is also a db id of subject (a business object for which the process is running and conditions are evaluated). To start process create subject and persist it. Then call controller.createSubject() with the ID of the document as userValue. This will create the process instance. Calling controller.touchSubject() with the same userValue will start the process asynchronously, calling controller.process() will do so synchronously. Don't forget to provide controller with implementation of Loader, which loads subjects for specified userVaules.

The Worklist

Several processes in a system may idependently create tasks and options. The worklist presents all tasks and options for a certain user in a localized, sortable and filterable manner. Furthermore it offers a means for locking work.

Process Elements one by one

All the process elements are implemented as Java- classes, that can either be handwritten or choosen from a library. Thus, a process can do everything, Java can and common requirememts are covered by the library. Most of the element's methods accept the subject as the only parameter.

Conditions

A Condition evaluates the subject and states whether it does apply or not. A temporal condition considers temporal parameters and makes a prediction, when its state will probably change. In some situations, a condition cannot be evaluated to true or false at any time in the process: its value is undefined.

public class Storniert
    extends AbstractCondition<UrlaubsAntrag>
{
    public boolean eval(UrlaubsAntrag subject) throws ConditionEvaluationException {
        return subject.getStorniert() != null;
    }
}
public class Due
    extends AbstractTemporalCondition<Issue>
{
    public boolean eval(Issue subject) throws ConditionEvaluationException {
        return subject.getDue().before(new Date());
    }

    public long getAnticipatedTransition(Issue subject) {
        return subject.getDue().getTime();
    }
}


If an activity is not reentrant, then the negated postcondition is appended to the precondition. Say so: execute, if the activity's precondition is met, but the postcondition does not already meet.

Synchronous Activities

A Synchronous Activity has a method execute, that is called from the controller as soon as its precondition matches. Actually matching the precondition, calling execute and matching the postcondition all happen in one transaction. It is committed if and only if no exceptions are thrown and the postcondition evals to true. Otherwise it is rolled back. A synchronous activity is configured with a number of trials and a retry delay. If all trials fail, the optional method escalate is called.

public class Eintragen
    extends AbstractSynchronousActivity<UrlaubsAntrag>
{
    GroupWare groupWare;

    public void setGroupWare(GroupWare groupWare) {
        this.groupWare = groupWare;
    }

    public void execute(UrlaubsAntrag subject) throws ActivityExecutionException {
        groupWare.addEvent(0, subject.getCreatedBy(), subject.getVonDatum(), subject.getBisDatum());
        subject.setEingetragen(new Timestamp(System.currentTimeMillis()));
    }
}

Asynchronous Activities

An Asynchronous Activity only has methods enlist and delist, that are called from the controller as soon as its precondition matches or doesn't match anymore. There is no execute method. Of course the activity's business logic cannot be perfomed in these methods, as execution will happen externally. But they can be used to prepare the work or cleanup after execution. The controller will enlist the activity, when the precondition matches and wait until it gets notified of the completion of the external work. For non optional activities a timeout starts with enlistment. If the activity is not completed within time, the optional method escalate gets called. An asychnronous activity is performed in two transactions. One is matching the precondition, enlisting and calling enlist. The other is the external execution, matching the postcondition and calling delist.

public class GoodsReceived
    extends AbstractAsynchronousActivity<Requisition>
{
    public void enlist(Requisition subject) throws ActivityExecutionException {
        System.out.println("enlist " + subject.getId());
    }

    public void delist(Requisition subject) throws ActivityExecutionException {
        System.out.println("delist " + subject.getId());
    }
}

User Activities and Actors

User Activities are a specialization of asynchronous activities, where the external work is performed by a user. On enlistment, the controller will ask the associated Actor whom to assign the work. Tasks can be forwarded, backwarded and delegated. Therefore the controller memorizes a forwarding level. When querying the actor, this level will be passed to the method getAssignees along with the subject. The Actor will typically use this level for walking up the organization hierarchy.

public class Stornieren
    extends FormClassNameActivity<UrlaubsAntrag>
{
    public void enlist(UrlaubsAntrag subject) throws ActivityExecutionException {
        System.out.println("enlist " + subject.getId());
    }

    public void delist(UrlaubsAntrag subject) throws ActivityExecutionException {
        System.out.println("delist " + subject.getId());
    }
}
public class Antragsteller
    extends AbstractActor<UrlaubsAntrag>
{
    public Set<String> getAssignees(UrlaubsAntrag subject, int level) {
        return new HashSet<String>(Arrays.asList(new String[] { subject.getCreatedBy() }));
    }
}

Events

Events are asynchronous activities without a precondition. They are performed externally. A method occured can be overridden in order to perform post processing. Completion is notified to the controller. There is no enlistment or assignment. On completion, the postcondition is checked. External work and completion happen in one transaction, that is only committed, if the postcondition evaluates to true. Events might be used to create a subject.

public class WasCreated
    extends FormClassNameCreateEvent<UrlaubsAntrag>
{
    public void occured(UrlaubsAntrag subject) throws ActivityExecutionException {
        System.out.println("occured " + subject.getId());
    }
}

Listeners

Listeners are synchronous activities without postconditions. They are called as soon as their precondition is met. The transaction is commited, if no exception is thrown. A listener typically does not change the subject. Listeners are often used to destroy a subject.

public class DestroyListener
    extends AbstractListener
{
    public void notify(Object subject) throws ActivityExecutionException {
        try {
            Map map = controller.getLoader().formatSubjectLines(subject);
            controller.destroySubject(controller.getLoader().idOf(subject));
        }
        catch (Exception e) {
            throw new ActivityExecutionException(e);
        }
    }
}

Expansions and Conclusions

Expansions and Conclusions are tools for the simplification of the graphical notation. A complex boolean expression can be shortened by introducing substitutions. Likewise a precondition can be simplified with conclusions and postconditions can be simplified with expansions. For example, for the subsequent process it probably won't mind, if a permission has been granted or was not required.

Demo Process Urlaubsantrag (Application for Leave)

Process Model
Process Model


The OSBL contains a comprehensive demo process with all important elements like user activities, tasks, options, actors, service integration, hibernate persistence and a wingS-based WebUI. Here is a snapshot of the model and the HTML documentation, generated from the process model. It shall server as the starting point for your own developments!

Generated Process Documentation (currently unavailable)

User Guide

The Command Line Tool

The commandline tool allows for administration of processes as well as diagnosis and manipulation of subjects. It provides a number of commands:

usage: concern PROCESS COMMAND ...
   where COMMAND ... is one of the following:

list [ACTIVITY]...
   Show enlistments of activities.
log SUBJECT...
   Print the log of a subject that is still in the process.
describe [ACTIVITY]...
   Describe all or some of the activities.
archive SUBJECT...
   Print the log of a subject that has finished the process.
create SUBJECT...
   Create a new subject.
process SUBJECT...
   Process a subject and wait for the completion of immediate activity.
touch SUBJECT...
   Announce a change of a subject.
complete ACTIVITY SUBJECT...
   Anncounce completion of an asynchronous activity.
check CONDITION SUBJECT...
   Check if the subjects match the condition.
post ACTIVITY SUBJECT...
   Check if the subjects match the precondition of the activity.
destroy SUBJECT...
   Destroy the subject.
pre ACTIVITY SUBJECT...
   Check if the subjects match the postcondition of the activity.

Developer Resources

API Documentation