[jboss-user] [jBPM] - Re: Integrating jBPM 5 into web application - architecture

Sandra Renaud do-not-reply at jboss.com
Thu Feb 7 08:46:04 EST 2013


Sandra Renaud [https://community.jboss.org/people/joploya] created the discussion

"Re: Integrating jBPM 5 into web application - architecture"

To view the discussion, visit: https://community.jboss.org/message/796530#796530

--------------------------------------------------------------
Hello Lisa and Anand,

I can't give you my application but this is the relevant code concerning the task management :

I use maven so I have these dependencies in the POM :
> <!-- jbpm -->
>      <dependency>
>                <groupId>org.drools</groupId>
>                          <artifactId>drools-compiler</artifactId>
>                          <version>5.4.0.Final</version>
>                     </dependency>
>                      <dependency>
>                               <groupId>org.jbpm</groupId>
>                               <artifactId>jbpm-bpmn2</artifactId>
>                               <version>5.4.0.Final</version>
>                               <exclusions>
>                     <exclusion>
>                           <groupId>dom4j</groupId>
>                           <artifactId>dom4j</artifactId>
>                     </exclusion>
>               </exclusions>
>                     </dependency>
>                     <dependency>
>                               <groupId>org.jbpm</groupId>
>                               <artifactId>jbpm-flow</artifactId>
>                               <version>5.4.0.Final</version>
>                               <exclusions>
>                     <exclusion>
>                           <groupId>dom4j</groupId>
>                           <artifactId>dom4j</artifactId>
>                     </exclusion>
>               </exclusions>
>                     </dependency>
>                     <dependency>
>                               <groupId>org.jbpm</groupId>
>                               <artifactId>jbpm-human-task-core</artifactId>
>                               <version>5.4.0.Final</version>
>                               <exclusions>
>                     <exclusion>
>                           <groupId>dom4j</groupId>
>                           <artifactId>dom4j</artifactId>
>                     </exclusion>
>               </exclusions>
>                     </dependency>
Then, the two java classes :
> import java.io.InputStream;
> import java.io.InputStreamReader;
> import java.io.Reader;
> import java.io.Serializable;
> import java.util.ArrayList;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> import java.util.Properties;
> 
> 
> import javax.annotation.PostConstruct;
> import javax.ejb.LocalBean;
> import javax.ejb.Stateless;
> import javax.enterprise.context.ApplicationScoped;
> import javax.enterprise.inject.Produces;
> import javax.persistence.EntityManagerFactory;
> import javax.persistence.PersistenceUnit;
> 
> 
> import org.drools.KnowledgeBase;
> import org.drools.SystemEventListenerFactory;
> import org.drools.builder.KnowledgeBuilder;
> import org.drools.builder.KnowledgeBuilderFactory;
> import org.drools.builder.ResourceType;
> import org.drools.io.Resource;
> import org.drools.io.ResourceFactory;
> import org.drools.logger.KnowledgeRuntimeLogger;
> import org.drools.logger.KnowledgeRuntimeLoggerFactory;
> import org.drools.runtime.EnvironmentName;
> import org.drools.runtime.StatefulKnowledgeSession;
> import org.jbpm.process.workitem.email.EmailWorkItemHandler;
> import org.jbpm.task.Group;
> import org.jbpm.task.User;
> import org.jbpm.task.identity.UserGroupCallbackManager;
> import org.jbpm.task.service.TaskService;
> import org.jbpm.task.service.TaskServiceSession;
> import org.slf4j.Logger;
> import org.slf4j.LoggerFactory;
> 
> 
> //import static org.junit.Assert.*;
> @Stateless
> @LocalBean
> public class KnowledgeSessionProducer implements Serializable{
> 
> 
>           private static final long serialVersionUID = -4494168896880405667L;
>           private Logger log = LoggerFactory.getLogger(KnowledgeSessionProducer.class);
>           private KnowledgeRuntimeLogger logger;
> 
>     @PersistenceUnit(unitName = "org.jbpm.task")
>     private EntityManagerFactory emf;
> 
>     public @PostConstruct void init(){
>               log.debug("init of KnowledgeSessionProducer ...");
>               TaskService taskService = new TaskService(emf, SystemEventListenerFactory.getSystemEventListener());
>         TaskServiceSession taskSession = taskService.createSession();
>         // Add users
>         @SuppressWarnings("rawtypes")
>                     Map vars = new HashMap();
>         InputStream usersin = KnowledgeSessionProducer.class.getResourceAsStream( "/LoadUsers.mvel" );
>         if(usersin != null) {
>                   Reader reader = new InputStreamReader( usersin );   
>                   @SuppressWarnings("unchecked")
>                   Map<String, User> users = ( Map<String, User> ) TaskService.eval( reader, vars );   
>                   log.debug("Users to load in db : ...");
>                   for ( User user : users.values() ) {
>                             taskSession.addUser( user );
>                             log.debug(" - "+user);
>                   }           
>         }
>         InputStream groupsin = KnowledgeSessionProducer.class.getResourceAsStream( "/LoadGroups.mvel" );
>         if(groupsin != null) {
>                   Reader reader = new InputStreamReader( groupsin );   
>                   @SuppressWarnings("unchecked")
>                   Map<String, Group> groups = ( Map<String, Group> ) TaskService.eval( reader, vars );     
>                   log.debug("Groups to load in db : ...");
>                   for ( Group group : groups.values() ) {
>                             taskSession.addGroup( group );
>                             log.debug(" - "+group);
>                   }
>         }
>         // try to get the usergroup callback properties
>         InputStream usergroupsin = KnowledgeSessionProducer.class.getResourceAsStream(  "/jbpm.usergroup.callback.properties" );
>         if(usergroupsin != null) {
>                   Properties callbackproperties = new Properties();
>                   try {
>                       // Properties.load(Reader) is a JDK 6 method
>                             callbackproperties.load(usergroupsin);
>                             UserGroupCallbackManager.getInstance().setCallbackFromProperties(callbackproperties);
>                             System.out.println("Task service registered usergroup callback ...");
>                   } catch (Exception e) {
>                             System.out.println("Task service unable to register usergroup callback ...");
>                   }
>         }
>         taskSession.dispose();
>         System.out.println("Task service started correctly!");
>         System.out.println("Task service running ...");
>     }
> 
>           @Produces
>           @ApplicationScoped
>           public StatefulKnowledgeSession produceKnowledgeSession(){
>                     log.debug("produce the KnowledgeSession ...");
>                     //Create the knowledgeBase
>                     /*This factory is used to build the knowledge base resources that are held collectively in KnowledgePackages.*/
>                     KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
> 
>                     //Add all processes to the knowledgeBuilder
>                     List<Resource> resources = getProcessDefinitionList();
>                     for (Resource resource : resources) {
>                               kbuilder.add(resource, ResourceType.BPMN2);
>                     }
> 
>                     /*Create a new KnowledgeBase from the knowledge packages that have been added to this builder. 
>                      * An exception is thrown if there are any errors.*/
> //                    assertFalse( kbuilder.hasErrors() );
>                     if ( kbuilder.hasErrors() ) {
>                          log.error( kbuilder.getErrors().toString() );
>                      }
>                     KnowledgeBase kbase = kbuilder.newKnowledgeBase();
> 
>                     /*Create a new StatefulKnowledgeSession using the default session configuration. 
>                      * Don't forget to dispose() session when you are done.
>                      * 
>                      * StatefulKnowledgeSession is the most common way to interact with the engine. 
>                      * A StatefulKnowledgeSession allows the application to establish an iterative conversation with the engine, 
>                      * where the state of the session is kept across invocations.*/
>                     StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
> 
>         logger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(ksession, "loggerFile", 1000);
> 
>         /*A work item manager is responsible for finding the right work item handler when a work item should be executed 
>          * and should be notified when this work item has been completed (or aborted).
>          * 
>          * Register the given handler for all work items of the given type of work 
>          * This part is done in the LocalHumanTaskService*/
> 
> //        ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler );
> 
>         ksession.getEnvironment().set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
> 
>         /*
>          * Register WorkItem Handler for Email
>          */
>         //EmailWorkItemHandler emailHandler =  new EmailWorkItemHandler();
>         //ksession.getWorkItemManager().registerWorkItemHandler("Email", emailHandler);
> 
>         return ksession;
>           }
> 
>           public KnowledgeRuntimeLogger getLogger(){
>                     return this.logger;
>           }
> 
>           private List<Resource> getProcessDefinitionList(){
>                     List<Resource> resourceList = new ArrayList<>();
>                     resourceList.add(ResourceFactory.newClassPathResource("workflows/MyFlow.bpmn2"));
>                     /**
>                      * TODO 
>                      * add all other process here
>                      */
>                     return resourceList;
>           }
> }
> 

> import javax.annotation.PostConstruct;
> import javax.enterprise.context.SessionScoped;
> import javax.enterprise.event.Event;
> import javax.faces.application.FacesMessage;
> import javax.faces.context.FacesContext;
> import javax.inject.Inject;
> 
> 
> import org.drools.runtime.StatefulKnowledgeSession;
> import org.jboss.seam.security.Identity;
> import org.drools.runtime.process.ProcessInstance;
> import org.jbpm.task.Status;
> import org.jbpm.task.query.TaskSummary;
> import org.jbpm.task.service.local.LocalHumanTaskService;
> import org.jbpm.workflow.instance.WorkflowProcessInstance;
> 
> 
> import com.st.ams.tools.ClaimEventListener;
> import com.ste.ws.authentication.seam.api.UserLDAP;
> 
> 
> /**
>  * Linked to the task management view
>  *
>  */
> public @Named @SessionScoped class TaskManager implements Serializable{
> 
> 
>           private static final long serialVersionUID = 7768657778155604411L;
> 
>           protected @Inject Identity identity;
>           private @Inject StatefulKnowledgeSession kSession;
>           private @Inject Event<ClaimEventListener> event;
> 
>           private List<Status> listStatus = new ArrayList<Status>();
> 
>           public org.jbpm.task.TaskService getTaskService(){
>                     return LocalHumanTaskService.getTaskService(kSession);
>           }
> 
>           private List<TaskSummary> userTaskList = new ArrayList<TaskSummary>();
>           private Map<String, List<TaskSummary>> groupTaskMap = new HashMap<String, List<TaskSummary>>();
>           private TaskSummary manageTask;
>           private List<String> groups;
> 
> 
> 
>           public @PostConstruct void init(){
>                     System.out.println("init task manager ...");
> 
>                     //Load user tasks
>                     listStatus.clear();
>                     listStatus.add(Status.Reserved);listStatus.add(Status.InProgress);
>                     System.out.println("load task list for user : "+((UserLDAP)identity.getUser()).getUser().getLogin());
>                     userTaskList = new ArrayList<TaskSummary>(getTaskService().getTasksAssignedAsPotentialOwnerByStatus(
>                                                                                 ((UserLDAP)identity.getUser()).getUser().getLogin(), 
>                                                                                 listStatus, 
>                                                                                 "en-UK"));
> 
>                     //Load groups and tasks for each group
>                     groups = new ArrayList<String>();
>                     for(String grp : ((UserLDAP)identity.getUser()).getUser().getGroups()){
>                  groups.add(grp);
>                  groupTaskMap.put(grp, getGroupTasks(grp));
>                     }
>           }
> 
> 
>           public List<TaskSummary> getUserTaskList() {
>                     if((userTaskList == null) || userTaskList.isEmpty()){
>                               listStatus.clear();
>                               listStatus.add(Status.Reserved);listStatus.add(Status.InProgress);
> 
>                //Trick because UserGroupCallBackImpl is not properly implemented
>                //TODO correction
>                               Set<TaskSummary> set = new HashSet<TaskSummary>(getTaskService().getTasksAssignedAsPotentialOwnerByStatus(
>                                                                                                                                                       ((UserLDAP)identity.getUser()).getUser().getLogin(), 
>                                                                                                                                                       listStatus, 
>                                                                                                                                                       "en-UK"));
>                               userTaskList = new ArrayList<TaskSummary>(set);
>                     }
>                     return userTaskList;
>           }
> 
>           /**
>            * In order to refresh the user task list
>            * This function allow to clear the content of the list
>            */
>           public void clearUserTaskList(){
>                     userTaskList.clear();
>           }
> 
>           /**
>            * In order to refresh the groups task list
>            * This function allow to clear the content of all lists
>            */
>           public void clearAllGroupTaskList(){
>                     List<String> keys = new ArrayList<>(groupTaskMap.keySet());
>                     for(String grp : keys){
>                               clearGroupTaskList(grp);
>                     }
>           }
> 
>           /**
>            * In order to refresh the group task list
>            * This function allow to clear the content of the list
>            */
>           public void clearGroupTaskList(String group){
>                     groupTaskMap.put(group, null);
>           }
> 
> 
>           /**
>            * return all group tasks available for the user
>            * @return List<TaskSummary>
>            */
>           public List<TaskSummary> getAllGroupTaskList() {
>                     List<TaskSummary> allGroupTask = new ArrayList<TaskSummary>();
>                     Iterable<List<TaskSummary>> mapValues = groupTaskMap.values();
>                     for(List<TaskSummary> entry : mapValues){
>                               allGroupTask.addAll(entry);
>                     }
>                     return allGroupTask;
>           }
> 
>           public List<String> getUserGroups(){
>                     if((groups == null) || groups.isEmpty()){
>                               groups = new ArrayList<String>();
>                               for(String grp : ((UserLDAP)identity.getUser()).getUser().getGroups()){
>  groups.add(grp);
>                               }
>                     }
>                     return groups;
>           }
> 
>           /**
>            * return tasks available for the group
>            * @param group
>            * @return List<TaskSummary>
>            */
>           public List<TaskSummary> getGroupTaskList(String group){
>                     if((groupTaskMap.get(group) == null) || groupTaskMap.get(group).isEmpty()){
>                               groupTaskMap.put(group, getGroupTasks(group));
>                     }
>                     return groupTaskMap.get(group);
>           }
> 
>           /**
>            * return tasks available for the group
>            * @param group
>            * @return List<TaskSummary>
>            */
>           public List<TaskSummary> getGroupTasks(String group){
>                     listStatus.clear();
>                     listStatus.add(Status.Ready);
> 
> 
>           //Trick because UserGroupCallBackImpl is not properly implemented
>           //TODO correction
>           Set<TaskSummary> set = new HashSet<TaskSummary>(getTaskService().getTasksAssignedAsPotentialOwnerByStatus(group, listStatus, "en-UK"));
>                     return new ArrayList<TaskSummary>(set);
>           }
> 
>           public void removeGroup(String group){
>                     groups.remove(group);
>           }
> 
>           public void addGroup(String group){
>                     if((group != null) && !group.isEmpty())
>                               groups.add(group);
>           }
> 
>           public void addGroupTask(String group){
>                     groupTaskMap.put(group, getGroupTasks(group));
>           }
> 
> 
>           /**
>            * Start a new processInstance of an existing Process
>            * and set the variables of this instance
>            * @param processId, map of variables, id of the requestor
>            * @return ProcessInstance created
>            */
>           public ProcessInstance startProcess(String processId, Map<String, Object> parameters){
>                     ProcessInstance p = kSession.startProcess(processId,parameters);
>                     return p;
>           }
> 
>           /**
>            * Return the WorkflowProcessInstance associated to a Task
>            * This instance allow to access the map of variables
>            * @return WorkflowProcessInstance managed
>            */
>           public WorkflowProcessInstance getWorkflowProcessInstance(long processInstanceId){
>                     return (WorkflowProcessInstance)kSession.getProcessInstance(processInstanceId);
>           }
> 
> 
>           /**
>            * Start a new processInstance of an existing Process
>            * @param processId
>            * @return ProcessInstance created
>            */
>           public ProcessInstance startProcess(String processId){
>                     return kSession.startProcess(processId);
>           }
> 
> 
>           /**
>            * When a user claim a task, the task go to RESERVED state
>            * Then we call start and the task goes to IN_PROGRESS state
>            * and is not visible for others
>            * @param task
>            */
>           public void claimTask(TaskSummary task){
>                     addMessage("task "+task.getId()+" claimed");
>                     setManageTask(task);
>                     getTaskService().claim(task.getId(), 
>                                         ((UserLDAP)identity.getUser()).getUser().getLogin());
>                     getTaskService().start(task.getId(), ((UserLDAP)identity.getUser()).getUser().getLogin());
>                     event.fire(new ClaimEventListener());
>           }
> 
>           /**
>            * return a task to group task
>            * @param task
>            */
>           public void revokeTask(TaskSummary task){
>                     addMessage("task "+task.getId()+" revoked");
>                     setManageTask(task);
>                     getTaskService().release(task.getId(), 
>                                         ((UserLDAP)identity.getUser()).getUser().getLogin());
>           }
> 
>           public void completeTask(TaskSummary task, Object results){
>                     getTaskService().completeWithResults(task.getId(), 
>                                         ((UserLDAP)identity.getUser()).getUser().getLogin(), results);
>           }
> 
>           /**
>            * The current manage task
>            * @return TaskSummary
>            */
>           public TaskSummary getManageTask() {
>                     return manageTask;
>           }
> 
> 
>           /**
>            * Set the currently manage task 
>            * (save it during the session)
>            * @param manageTask
>            */
>           private void setManageTask(TaskSummary manageTask) {
>                     this.manageTask = manageTask;
>           }
> 
> 
>           /**
>            * faces message rendered
>            * @param message to display
>            */
>           public void addMessage(String summary) {  
>         FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary,  null);  
>         FacesContext.getCurrentInstance().addMessage(null, message);  
>     } 
> 
> }
> 
You have to implement the UserGroupCallBackImpl. (See the doc for that :  http://docs.jboss.org/jbpm/v5.4/userguide/ch.human-tasks.html#d0e5419 http://docs.jboss.org/jbpm/v5.4/userguide/ch.human-tasks.html#d0e5419)

You have to register your implementation of usergroupcallback by creating a file jbpm.usergroup.callback.properties in the folder resources.
> jbpm.usergroup.callback=com.your.package.path.with.dot.MyUserGroupCallbackImpl
  https://community.jboss.org/servlet/JiveServlet/showImage/2-796530-20279/resources.png  https://community.jboss.org/servlet/JiveServlet/downloadImage/2-796530-20279/252-141/resources.png 


The persistence.xml must be configured like this :
--------------------------------------------------------------

Reply to this message by going to Community
[https://community.jboss.org/message/796530#796530]

Start a new discussion in jBPM at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20130207/ad120d8c/attachment-0001.html 


More information about the jboss-user mailing list