[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