There are no perfect rules to model your workflow, depending on your needs for the process and the executors involved. In any case, I 'd like to share with you the key rules that developers generally agree. If you agree or want to give me some suggestions, please submit them to me.
- Keep your jbpm
Executioncontext
Clean
In the first formal jbpm project I have ever seen, I noticed that developers sometimes use executioncontext to place many process variables. Adding variables to executioncontext is a basic rule to control the execution flow. However, do not be tempted to put anything in it! For example, suppose you are designing a complicated ticket sales system: you may need to store additional information about the performer, such as name, last name, and email. Therefore, you have mixed the business variables and process variables in the execution context!
A good solution is to construct these fields in an EJB and keep only one ticketid in your executioncontext.
The following is an example of an EJB that uses seam to interact with a business flow:
@ Stateful <br/> @ name ("ticketingsystem") <br/> public class ticketbean implements ticketbeanitf {<br/> @ persistencecontext (type = persistencecontexttype. extended) <br/> entitymanager em; <br/> @ in (create = true) <br/> @ out <br/> private ticket; <br/> // we make this available to the Business Process <br/> @ out (scope = scopetype. business_process, required = false) <br/> long ticketid; <br/> @ CreateProcess (definition = "troubleticketing") <br/> Public void createticket () {<br/> em. persist (ticket); <br/> // keep a reference to the ticketid in your biz Process <br/> ticketid = ticket. getticketid (); <br/>}< br/>}
@Stateful @Name("TicketingSystem") public class TicketBean implements TicketBeanItf { @PersistenceContext(type=PersistenceContextType.EXTENDED) EntityManager em; @In(create = true) @Out private Ticket ticket; // We make this available to the business process @Out(scope=ScopeType.BUSINESS_PROCESS, required=false) long ticketId; @CreateProcess(definition="TroubleTicketing") public void createTicket() { em.persist(ticket); // Keep a reference to the ticketId in your biz process ticketId = ticket.getTicketId(); } }
Adding domain variables to executioncontext at will not only serves as a poor design option, but also greatly reduces the performance of your processes.
- Jbpm exception processor is only used to set variables or make error notifications.
Jbpm has a built-in exception processor that can be applied to a single node or the entire process.
<Exception-handler exception-class = "Java. lang. exception "> <br/> <action class =" com. sample. handlers. bpmexceptionhandler "> <br/> </Action> <br/> </exception-handler> <br/>
<exception-handler exception-class="java.lang.Exception"> <action class="com.sample.handlers.BPMExceptionHandler"></action> </exception-handler>
You may have been tempted to use an exception processor in jbpm to make decisions on execution streams. Do not do this! The jbpm mechanism is not completely similar to Java Exception Handling. in Java, a caught exception can affect the control flow. In jbpm cases, the control flow cannot be changed by the Exception Handling Mechanism of jbpm. Exceptions can be caught or not captured. Non-captured exceptions are thrown to the client (for example
The token. Signal () method client) or the exception is caught by the jbpm exception processor. For captured exceptions, graph
Execution will continue execution as there is no exception.
The best practice for using an exception processor is to execute the related actions (set variables, send emails, JMS messages, etc.), or continue graph execution (what you expect) or throw an exception again because of a transaction failure and ends the current node and returns to the starting state.
Depending on thrown exceptions, capturing business exceptions in your actions and setting some process variables is also a good design. Then you can construct a decision node in the process to select a specific execution path.
- Need jbpm to do failed forwarding? Encapsulate jbpm calls in a cluster's slsb (stateless session bean)
Jbpm is a state machine: the state of process description and runtime is persisted to the database, but in a cluster environment, they do not automatically fail to forward. If a cluster node fails, some triggers (ui, JMS, and repetition timer) that are being executed need to be stopped and have to be restarted. Depending on your transaction context, these actions can be automatically executed (re-pass the JMS message,
Re-execute the timer) or request UI interaction (if the cluster node is down and needs to be restarted, an error message is displayed to the user ).
Therefore, when the process description is persistent, the failed forwarding of the workflow must be executed manually. Jbpm can be used to build a complete failure protection solution that supports failed forwarding in clusters, but it does not support out-of-the-box use.
So what is the simplest way to add these features to your workflow? In most cases, the best solution is to use a stateless Session Bean in your application to encapsulate jbpm API calls and build a cluster at the end.
Adding cluster capabilities to your EJB is not complicated at all. refer to the following solution:
Http://www.mastertheboss.com/en/jboss-application-server/49-jboss-ejb3-in-a-cluster.html
- Use super States wherever possible
A superstate is a set of nodes. It is a convenient way to combine nodes into a set of related nodes and represents the instance stage in the process. For example, an application can combine all nodes in a process in stages. Action can be associated with a superstate event. An important thing is that a token can be nested in multiple layers at a given time. This allows you to easily check whether a process is executed, for example, in the initial stage.
Therefore, when every State represents a stage of a process, splitting the process out of super states is a good design, but why I advocate the use of super States for more reasons:
Jbpm is a state machine and does not deliver a built-in graphical environment. The official Eclipse plug-in allows you to use graphical process modeling, but it is not the best BPM front-end tool in the market: the icon is too big, too ugly, you cannot customize icons for different node types. If you used jbpm to draw a process with 100 nodes, you may also do what I did: because the process picture is large and messy, I designed a front-end presentation layer from jbpm.
If you do not want to design a new front-end for jbpm, use superstates as widely as possible, which will make your process (diagram) more readable, and when you show a 5-page flowchart, your boss will not be dizzy.
- Try to expand jbpm APIs instead of messing up complicated process modeling
Sometimes developers (I am also) Don't look for simpler solutions, maybe using the built-in nodes of jbpm to model the process and lead to an unnecessary complicated process.
For simplicity ......
Jbpm is very scalable (action handlers, custom node type) and sometimes easier than using existing nodes for Simple Modeling! This makes things less complex.
For example, if you have such a requirement, assign a task in a specific track depending on geographical positioning. (If a task occurs in New York, it is assigned to user A, and if it occurs in Chicago, it is assigned to user B)
Get the org. jbpm. taskmgmt. Def. task. Java class and add the following fields and methods:
Private string tasklocation; <br/> Public String gettasklocation () {<br/> return tasklocation; <br/>}< br/> Public void settasklocation (string tasklocation) {<br/> This. tasklocation = tasklocation; <br/>}
private String taskLocation; public String getTaskLocation() { return taskLocation;}public void setTaskLocation(String taskLocation){ this.taskLocation = taskLocation;}
Modify the hibernate configuration file for task. Java in task. HBM. xml:
<Property name = "tasklocation" column = "tasklocation _"> </property>
Finally, modify jpdlxmlreader. Java to inject new attributes into the task class when the process is read from the database.
String tasklocation = taskelement. attributevalue ("tasklocation"); <br/> If (tasklocation = NULL) {<br/> tasklocation = taskelement. attributevalue ("tasklocation"); <br/>}</P> <p> If (tasklocation! = NULL) {<br/> task. setlocation (tasklocation); <br/>}< br/>
String taskLocation = taskElement.attributeValue("taskLocation");if (taskLocation==null) { taskLocation = taskElement.attributeValue("taskLocation");} if (taskLocation != null){ task.setLocation(taskLocation);}
Another custom example can be applied to your query. Suppose you want to use many rules to filter your tasks: consider a list of tasks that use JSF for rendering and a task filtering window, in this window, you can filter tasks by priority, date, executor, and task name.
One way to implement things that won't make things more complicated is to add a filter to the task instance: simply open the hibernate file of the task instance and add some hibernate filters:
<Filter Name = "filterpriority" condition = ": parampriority = Priority _"/> <br/> <Filter Name = "filterdesc" condition = ": paramdesc = Description _ "/> <br/> <Filter Name =" filterid "condition =" STR (ID _) Like (: paramid) "/> <br/> <Filter Name =" filtercreate "condition =" create _ between: paramfrom and: paramto "/>
Note that the parameter passed to the filter starts with ":", and other fields (such as _ id) belong to taskinstance. Then, when you fill your database, make the selected filter take effect:
String SQL = "from org.jbpm.taskmgmt.exe. taskinstance "; <br/> session. enablefilter ("filterpriority "). setparameter ("parampriority", "2"); <br/> query queryparent = session. createquery (SQL); <br/> List list = queryparent. list (); <br/> iterator iter = List. iterator (); <br/> while (ITER. hasnext () {<br/> taskinstance = (taskinstance) ITER. next (); <br/>}
<filter name="filterPriority" condition=":paramPriority = PRIORITY_"/> <filter name="filterDesc" condition=":paramDesc = DESCRIPTION_"/> <filter name="filterId" condition="str(ID_) LIKE (:paramId) "/> <filter name="filterCreate" condition="CREATE_ BETWEEN :paramFrom and :paramTo"/>
String sql = "from org.jbpm.taskmgmt.exe.TaskInstance";session.enableFilter("filterPriority").setParameter("paramPriority","2");Query queryParent = session.createQuery(sql); List list = queryParent.list();Iterator iter = list.iterator(); while (iter.hasNext()) { TaskInstance taskInstance = (TaskInstance)iter.next(); }
- If you have complex rules, hire a drools developer
First, you must understand:
A workflow engine (or traditional Graph-Oriented Programming) is about developing a graph that represents execution. Nodes can be displayed as waiting.
A rule engine is used to specify a set of rules and then apply a inference algorithm to the specified set of rule libraries.
How does drools work with jbpm? A best practice is to use jbpm to embody all or part of the logic in the handlers in a rule engine. In other words, the jbpm engine can be driven by the drools rule engine.
Based on other ideas, this practice is not applicable to all situations, so ask yourself a few things:
My Java actions
How complicated is handlers? If you only need to read some data from the database and do not need more data, this may not be suitable for a rule engine. However, when Java is used to implement a process that handles a large number of business rules, it is worth considering drools when you use the jbpm engine for your process management. This is because most application development will become more and more complex over time, and drools will make it easy for you to cope with this, especially if your application has a long life cycle. Furthermore, drools can help you deal with future business rule changes by specifying business rules in one or more XML files that are easily configured.
Another score point of drools is that drools "guides" developers to write code correctly to "do the right thing ". At the same time, rules are easier to read than coding, so your staff will be more comfortable reading the business.
Furthermore, drools can remember not only information, but also test results using the information in the past to quickly improve the entire application.
BPEL is an XML language used to describe the interaction of long-running Web Services. It is mainly used to centrally orchestrate message exchanges, so it is a key element in SOA.
What do BPEL and jpdl have in common?
- Both languages can describe the process
- Interaction with external proxies
- Schedule activities
- Exception Handling
- Error Recovery
Even if they have something in common, the specific expressions of these elements lead to different audiences to discuss their descriptions of the process:
- Jpdl uses simpler semantics to describe the organizational process
- BPEL uses complex scenarios to describe the structural composition
The interaction with external proxies is also implemented differently:
- It is document-oriented, so it can be used across the company.
- Jpdl is object-oriented, so it can serve as the backbone of the company's application components
- BPEL proxies interaction between people to the partner service for implementation
- Jpdl provides integrated task management
So when should I use BPEL?
- When you need your process to be easily stretched out of the Java platform-the BPEL process can be executed on a server based on the Java platform or any other software platform (such as. net. This is particularly important when business interaction is performed between partners on different platforms.
- When there is no direct personnel involved (that is, a process without manual intervention), and you need to support long-running business processes well.
- When you need to obtain transaction compensation in a relatively simple way. Compensation or cancellation steps in a fully successful business process are the most important concepts in the business process. The goal of the compensation is to cancel, that is, to eliminate the impact of some of the nodes that have been abandoned in a business process that have been executed.
Use jpdl when these conditions are not met.
Original article: http://www.mastertheboss.com/en/jbpm/106-jbpm-best-practices.html