Pages

Sunday, October 16, 2011

Working with the Human WorkList api and create your own WorkList application

In this blogpost I will explain what is possible with the IWorkflowServiceClient ( HumanTask java client )  so you can integrate this in your own Custom WorkList application.  This way you don't need to use the standard BPM worklist application, add some extra functionality and also don't need to create HumanTask ADF Task Flow and deploy this to the SOA Suite server.

This demo shows you the power of Fusion Middleware where you can combine SOA Suite workflow to your own ADF applications.

At the end of this blogpost I will show you the link for this demo application which also contains the BPEL to create the HumanTasks.

Here are some pics of the demo application. You will get an overview of the tasks assigned to the weblogic user ( normally this will be replaced by the user of the application ). The user can search on certain field, change the ordering and control the maximum rows.


And in combination with the ADF UIShell template of Oracle you can make a multi task handling application. Every task you click on will have its own Tab. Here you can also lookup the extra information which is necessary to the user so it can handle this task.



Time to go back to the code.

I will start with a BPEL which invokes a HumanTask and to make my life easy I will use the flexible text , date or url fields of the HumanTask for my own important data so I don't need to examine payload.
This way you can search on these fields and use it in your own task entity.



And map the payload fields to the flex fields in a Assign activity. These fields are located in the systemMessageAttributes element.


Next is to retrieve these tasks from the java / ejb client. Todo so I need two libraries bpm-infra.jar and bpm-services.jar. Copy these jars from the soa server so you don't get serial id versioning errors.

I will use on behalf of so I don't need to have the password of the user and I can do all the actions of behalf of this user.

Start with a property file or you can set some java parameters

soa.properties
soaserver=soaps3.alfa.local:8001
humantask.user=weblogic
humantask.password=weblogic1

or set these java parameters on the project
-Dhumantask.url
-Dhumantask.user
-Dhumantask.password

For the tasks I will connect to the HumanTask EJB and for the Identities I need to connect the Identity SOAP Service.


We need to have an IWorkflowContext which I can use for the query operation on the Task bean. I will first authenticate with the superuser and then on behalf of the user of my application.

In this query on the human task I can control which attributes I want to use in my application.

List<String> queryColumns = new ArrayList<String>(); queryColumns.add(TableConstants.WFTASK_TITLE_COLUMN.getName());

And if I want to have the payload or the comments, I need to do this.
List<ITaskQueryService.OptionalInfo> optionalInfo =
    new ArrayList<ITaskQueryService.OptionalInfo>(); optionalInfo.add(ITaskQueryService.OptionalInfo.COMMENTS); optionalInfo.add(ITaskQueryService.OptionalInfo.PAYLOAD);

Do ordering on the tasks.

Ordering taskOrdering = null;
if ( "PRIO".equalsIgnoreCase(orderBy) ) {
 taskOrdering = new Ordering(TableConstants.WFTASK_PRIORITY_COLUMN, true,false);
 taskOrdering.addClause(TableConstants.WFTASK_TASKNUMBER_COLUMN, true,false);
} else if ("ID".equalsIgnoreCase(orderBy) ) {
  taskOrdering = new Ordering(TableConstants.WFTASK_TASKNUMBER_COLUMN, false,true);
} else if ("ESC_DESC".equalsIgnoreCase(orderBy) ) {
  taskOrdering = new Ordering(TableConstants.WFTASK_EXPIRATIONDATE_COLUMN, false, false);
} else if ("ESC_ASC".equalsIgnoreCase(orderBy) ) {
  taskOrdering = new Ordering(TableConstants.WFTASK_EXPIRATIONDATE_COLUMN, true, false); }
}

It is also possible to do a search and add a fixed where condition. For this we need to have a Predicate where we can add the states we want to see.

List<String> correctStates = new ArrayList<String>(); correctStates.add(IWorkflowConstants.TASK_STATE_ALERTED); correctStates.add(IWorkflowConstants.TASK_STATE_ASSIGNED);

Predicate predicateBasic = new Predicate(
  TableConstants.WFTASK_STATE_COLUMN,
  Predicate.OP_IN,
  correctStates);

predicateBasic.addClause(Predicate.AND,
 TableConstants.WFTASK_STATE_COLUMN,
 Predicate.OP_NEQ,
 IWorkflowConstants.TASK_STATE_STALE);

This Predicate can be combined to an other Predicate with an other AND / OR and finally added to the queryTasks method of the workflowServiceClient.getTaskQueryService()


To make your life easier try to convert the tasks to your own entity  so you can use your own attributes instead of using text1 etc.

You can download, fork or improve the Demo application at github https://github.com/biemond/soa11g_examples/tree/master/HumanTaskListApp

40 comments:

  1. Its very interesting post .How did u converted the task to entity? I mean whats the starting point for Task project.

    ReplyDelete
  2. Hi Edwin,

    We are just starting a project yhat uses BPM 11 and ADF. I'd lik to know your opinion about approach to integrations thes technologies. Oracle advocates to use adf taskflows inside BPM Workspace. In my opinion this is good aproach for small application with small form to update process data. Except this, all data should be stored in database, so in fact we develope large business components based application. I think, that better way would be create generic adf application (BC + ADF RC) with custom worklist as started page as you described in this post. What is your opinion ?
    I also thing that approaches to build Human Tasks based ADF apps is a good issue for discuss on EMG.

    ReplyDelete
  3. Hi,

    in https://github.com/biemond/soa11g_examples/blob/master/HumanTaskListApp/Tasks/src/nl/whitehorses/fcforms/tasks/services/HumanTaskClient.java

    I convert theses task in List getHumanTasks of the HumanTaskClient class

    and in TaskConvertor I do the transformation

    https://github.com/biemond/soa11g_examples/blob/master/HumanTaskListApp/Tasks/src/nl/whitehorses/fcforms/tasks/utility/TaskConvertor.java

    thanks

    ReplyDelete
  4. Hi Jakub,

    Mostly users don't want to go to a different application ( or a few times a day ), that's why oracle also made it possible in webcenter.

    Mostly you already have a web application where you can integrate this and this application already have all the data the user needs to decide.

    We use a human task textattibute for the taskflow type and some others for the primary keys. With this we can start the specific Task flow and the generic one ( for approval , comments etc)

    this works great and the users think that the workflow is part of the application.

    I know for sure that fusion apps does the same.

    thanks

    ReplyDelete
  5. Hi Edwin,

    thanks for response. We have a dillema between two options:

    1) Build an adf applcation contains BC Model and deploy as a part of BPM Proces Workflow - Oracle suggests this way - in my opinion it's good for small applicatiosn without tabs and complex menu and complex BC model (we need this to persis process data into DB)

    2) Build independent adf application and on the start page display for user his tasks using way you show in this blog post. In my opinon this is the better approach. All we need to get from BPM is task ID, availabe actions and payload (in fact only ID of user application - anyway rest of data we have to get from database not from process).

    Your opinion would be appreciated.

    ReplyDelete
  6. Hi,

    It depends , are you using SOA or bpm with SOA. I heard good things about the new bpm ps4 , where you can customize the work list app.

    But I know you, so you should be able to build the app but if you don't have java web developers go for option 1

    Thanks

    ReplyDelete
  7. Thanks for response Edwin. We are not planning to use SOA - only BPM. It's true - bundeled Worklist is customizable. My doubts affect communication between BPM and ADF. Using Oracle way we generate task flow for all human task, but:
    1) For all human task JDev generates also separate data control stack (in my opinion it should be only one communication point between BPM and all ADF app)
    2) In all task flows there are automatically registered a lot of page flow scope beans and params (not described anywhere - documentation is not asset of BPM 11 :))

    My key doubt is that using oracle approach we unnecessarily will create to complex application.
    As I mentioned before, we will persist process data using BC, so only data we need form payload is ID of master-level row.

    P.S. I think we should invite Andrejus for this discussion and move it to EMG :)

    ReplyDelete
  8. Suppose that in your SOA composite you assign certain human tasks to a group. Then a user belonging to that group wants to acquire a task thru its taskId. Is it correct that you first call TaskService.releaseTask(ctx, taskId) and then acquireTask(ctx, taskId)? It does not work for me if I try to use the same user context (new task owner) in both cases. It remains assigned to group. How are you supposed to create IWorkflowContext for a group? It's supposed to represent a user having a password etc..

    ReplyDelete
  9. is there API for the process? not only human workflow. e.g. I can suspend/resume the process instance even if it is not in human task stage. thanks.

    ReplyDelete
  10. Hi,

    Suppose that in your SOA composite you assign certain human tasks to a group. Then a user belonging to that group wants to acquire a task thru its taskId. Is it correct that you first call TaskService.releaseTask(ctx, taskId) and then acquireTask(ctx, taskId)?

    if it is not acquired then you can acquire it. if it is then you need to have permission to release it and acquire.

    It does not work for me if I try to use the same user context (new task owner) in both cases. It remains assigned to group.

    it will always be assigned to this group. only acquire is changed. but you can assigned it to an other group or person.

    How are you supposed to create IWorkflowContext for a group?

    not possible , a person can belong to a group.

    thanks

    ReplyDelete
  11. Yeah,no need to not call release if a task is assigned to group:-)

    I also realized the importance of acquiredBy attribute. If a user acquires a task which was originally assigned to a group, the acquiredBy field can serve as an indicator of that. The assignee lists and task state ( ASSIGNED) do not change in that case.

    ReplyDelete
  12. Yeah,no need to not call release if a task is assigned to group:-)

    I also realized the importance of acquiredBy attribute. If a user acquires a task which was originally assigned to a group, the acquiredBy field can serve as an indicator of that. The assignee lists and task state ( ASSIGNED) do not change in that case.

    ReplyDelete
  13. Hi

    Thanks a lot for the post. Am new to this and was wondering if you have any step by step documentation of how you built this application.

    By the way ,am using 11.1.1.6 and when I deploy the demo application i am getting the following error, looks to me like version issue, any pointers on how to solve this would be great

    java.rmi.UnmarshalException: oracle.bpel.services.workflow.repos.PredicateConstants; local class incompatible: stream classdesc serialVersionUID = 5970371950924981312, local class serialVersionUID = 2394121507118571727; nested exception is: java.io.InvalidClassException: oracle.bpel.services.workflow.repos.PredicateConstants; local class incompatible: stream classdesc serialVersionUID = 5970371950924981312, local class serialVersionUID = 2394121507118571727

    Regards
    Venkat

    ReplyDelete
    Replies
    1. Hi,

      Can you update your bpm jars , I used the PS3 version and you need PS5

      Next is to retrieve these tasks from the java / ejb client. Todo so I need two libraries bpm-infra.jar and bpm-services.jar. Copy these jars from the soa server so you don't get serial id versioning errors.

      in https://github.com/biemond/soa11g_examples/tree/85c412ff11f1f8b30b572f1a1ec6042af12d39a1/HumanTaskListApp/HumanTaskSOA there is a composite, how to add a humantask from bpel.

      thanks

      Delete
    2. Edwin

      Thanks a lot for the response. Can you please tell me the name of the bpm jars that needs to be updated. I tried to include all the libraries of BPM but still am getting compilation error.

      Regards
      Venkat

      Delete
    3. Hi,

      you need to replace bpm-infra.jar (3mb) and bpm-services.jar (almost 11mb ) with the jar versions located on your soa server, these jar are in the web-inf/lib of the viewcontroller project.

      thanks

      Delete
    4. Thanks Edwin....that worked

      Delete
    5. Hi Edwin,

      We have a requirement to trigger membership requests for WebCenter Spaces. Based on the Oracle documentation we have integrated SOA Suite BPEL flow with WebCenter Spaces. But, there are some issues coming. Our Spaces application has custom look and feel which might not be directly used from the OOTB worklist task flow. Is there any workflow Java API to request the membership as well as viewing and accepting or rejecting those requests ?

      Delete
  14. Hi Edwin,

    We have a requirement to moderate the member request for a particular WebCenter Group Space. Based on the documentation, we have integrated SOA Suite BPEL flow with WebCenter Spaces for performing this approval process. But, after configuring SOA Suite BPEL flow with WebCenter Spaces, we are not able to see the member requests in the worklist. Now, in our application we need to show the pending requests in a customized way. Is there a way we can use some Workflow APIs to initiate this membership request and then see all these pending tasks as well as use APIs to accept or reject threquest ?

    ReplyDelete
  15. Hi Edwin,

    We have a requirement to trigger membership requests for WebCenter Spaces. Based on the Oracle documentation we have integrated SOA Suite BPEL flow with WebCenter Spaces. But, there are some issues coming. Our Spaces application has custom look and feel which might not be directly used from the OOTB worklist task flow. Is there any workflow Java API to request the membership as well as viewing and accepting or rejecting those requests ?

    ReplyDelete
    Replies
    1. Hi,

      Indeed you can make your own Task Flow , Portlet etc. you can invoke uthe Human WorkFlow Web services http://biemond.blogspot.nl/2012/04/how-to-use-human-workflow-web-services.html or use the java client api like in this blogpost, to query, accept and decline the human tasks. The world is yours.

      Delete
  16. Hi Edwin,

    We have a requirement to trigger membership requests for WebCenter Spaces. Based on the Oracle documentation we have integrated SOA Suite BPEL flow with WebCenter Spaces. But, there are some issues coming. Our Spaces application has custom look and feel which might not be directly used from the OOTB worklist task flow. Is there any workflow Java API to request the membership as well as viewing and accepting or rejecting those requests ?

    ReplyDelete
    Replies
    1. Hi,

      In this blogpost I am using the java api which talks against the EJB which can do all ,but you can customize the WorkList application and Human Task Flow with your own look and feel.

      thanks

      Delete
  17. Hi Biemond,

    I am trying to create a custom app for worklist.
    I have followed your blog and oracle doc.
    While reassigning a task i am getting below error

    java.lang.RuntimeException: Invalid action on workflow task or user does not have privilege to perform this action.
    Action RELEASE on task b517db5d-b313-4437-93f1-7b64ad017aec cannot be performed by pavan.
    Make sure that the action is valid with respect to the current state of the task or ensure that the user has privilege to perform this action on the workflow task.

    what could be the reason?
    Both current user and future user are part of Administrators group and value of state is ASSIGNED

    ReplyDelete
    Replies
    1. Hi,

      Did you first do an acquire.

      Thanks

      Delete
    2. I have the same issue, Pavan, did you find the reason?

      Delete
  18. Great post!

    I'm having an issue, perhaps you could assist me; in order for users to start working on a task they first need to claim it, right? but when they do an error message appears saying:

    “The task is already modified. The task was modified before the current action could be performed. Refresh the task and perform the action again if the action is still relevant on the refreshed.”

    We implemented a quick fix which basically refreshes the form when finished loading, this updates the client side payload and prevents this error from happening, but it is not the best solution since we are forcing a refresh and in some cases depending on the payload size could take a while.

    Do you know why is this error happening and how can we fix it?

    ReplyDelete
    Replies
    1. Hi,

      very strange, do you have some PPR action going on and do you invoke acquiretask in the pagedef of the page.

      Thanks

      Delete
    2. I too getting the same error. As per Oracle this is because "numberOfTimesModified" field in the task object is out of sync. You need to first retrieve the current task object before
      performing any other updates. Is there any way to fix with out refreshing the same.

      Delete
  19. while executing the code, I ma getting below exception in eclipse.

    oracle.bpel.services.workflow.client.WorkflowServiceClientException: weblogic.rjvm.PeerGoneException: ; nested exception is:
    weblogic.utils.NestedException: java.lang.NoClassDefFoundError: oracle/xml/jaxb/JaxbNode

    ould you pls help me where I can get the jar, which ahving the classes oracle.xml.jaxb

    thanks in advance

    ReplyDelete
    Replies
    1. Hi,

      I think you need to xmlparvserv2.jar and / or xml.jar located in the oracle_common\modules\oracle.xdk_11.1.0 folder

      thanks

      Delete
  20. Hi Edwin

    I am trying to write a custom bpm workspace kind of page, by querying the tasks for a user like above.
    I am able to query the tasks for the user with hardcoded username and password, but in actual implementations it is not accepted or possible to get user password.
    I am using BPM, but I think the API should be same.

    1. First of all our application will be SSO enabled and the authentication will be done by AD.
    Users will not even have to login to the application, but the application will be using windows authentication.
    So I cannot use the taskQueryService.authenticate() method because I will not know the logged in password.
    Is there any other way to get the IWorkflowContext without having to send the password.
    I do understand that in the BPM Task UI ADF page, we can query the tasks and get the workflow context for the logged in user,
    but my page will not have all those pageFlowScope parameters like (bpmWorklistContext etc).
    First I need to query the tasks list and then only we can open the tasks pages.

    2. As an alternative to the above approach, I tried to assign a user as process owner and use this user for authentication (to get all the tasks)
    and then hoping to filter the tasks based on the assignees. (assuming the assignees are users and not groups)
    My intention is to add a predicate clause to filter the user.
    But task.getSystemAttributes().getAssigneeUsers() API is also returning the user role name, but not the logged in user id.
    Is there a way to get the logged in user id?

    3. Assuming that I get all the tasks as the process owner, Is there a predicate we can define with the logged in user id ? so that I can display tasks assigned only to that user ?

    Thanks for your time.
    Sameer

    ReplyDelete
  21. Hi,

    just do like me and use OnBehalfOf, create a super user ,authenticaten and this context for OnBehalfOf
    taskQueryService.authenticateOnBehalfOf(context, onBehalfOfUser);

    Thanks

    ReplyDelete
  22. Hi Edwin,
    Thanks for this post which is very helpful me.

    but I have a problem and can not find the solution, I need to access BPM tasks through its URL,
    to form the url of the task need the following minimum parameters

    http://host:port/project
    ?bpmWorklistTaskId=6cee1168-e778-438d-80c0-af4b82ec1780
    &bpmWorklistContext=82ef26a2-ce7e-4e39-9b6b-ec5a........
    &bpmWorklistHttpURL=url

    get the parameter missing is the "& bpmWorklistContext" which is very similar to token session but not equal.
    The url formed from the webService a java client application that consumes BPM services.

    Any tips?
    Regards, Stephen

    ReplyDelete
    Replies
    1. Hi,

      I think you need to authenticate to have this Context like I do in this blogpost.
      Don't know what you build will work

      Can't you use this workflow api , its all the same ( all HWF)

      thanks

      Delete
  23. Hi,

    I am able to compile the code but when i tried to run it gives me this error,
    "main" java.lang.NoClassDefFoundError: oracle/j2ee/ws/common/jaxws/ServiceDelegateImpl

    my eclipse IDE has all the necessary jars and these jar files ,
    xmlparserv2.jar, xml.jar, wsclient.jar . Pleaseadvise me which one i am still missing.



    ReplyDelete
  24. hi,

    I am trying to perform two actions in my code- reassign and deleteTask. When i am running the code the reassign function is working fine but for delete task it throws an error-:
    ORABPEL-30036

    Invalid action on workflow task or user does not have privilege to perform this action.
    Action DELETE on task b39c8173-e976-404c-b019-403787507e9b cannot be performed by weblogic.
    Make sure that the action is valid with respect to the current state of the task or ensure that the user has privilege to perform this action on the workflow task."
    I have allready given admin priviledge to weblogic

    Can anyone help me out with a possible solution?

    ReplyDelete
  25. Hi,
    Thanks for the post !

    I have problem with getting the date of task process initiation.
    The customer requires showing initiation of task process on the tasks table. (loan request date)
    I used createDate, but it returns the date of current task creation,

    how can I access to the date by API ?

    Thanks !

    ReplyDelete
  26. Hi Edwin,

    Great post. I used the same API to build custom worklist using SOA 12c. I copied required JAR files from 12c server to my application and deploying to ADF domain. I am getting below exception. Any inputs will be greatly appreciated.


    ReplyDelete
    Replies
    1. Is there any specific care to be taken to implement this using 12c (12.2.1)?
      Unable to create the "IWorkflowServiceClient" instance. Receving NULL value.

      Delete