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
Its very interesting post .How did u converted the task to entity? I mean whats the starting point for Task project.
ReplyDeleteHi Edwin,
ReplyDeleteWe 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.
Hi,
ReplyDeletein 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
Hi Jakub,
ReplyDeleteMostly 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
Hi Edwin,
ReplyDeletethanks 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.
Hi,
ReplyDeleteIt 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
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:
ReplyDelete1) 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 :)
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..
ReplyDeleteis 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.
ReplyDeleteHi,
ReplyDeleteSuppose 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
Yeah,no need to not call release if a task is assigned to group:-)
ReplyDeleteI 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.
Yeah,no need to not call release if a task is assigned to group:-)
ReplyDeleteI 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.
Hi
ReplyDeleteThanks 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
Hi,
DeleteCan 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
Edwin
DeleteThanks 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
Hi,
Deleteyou 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
Thanks Edwin....that worked
DeleteHi Edwin,
DeleteWe 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 ?
Hi Edwin,
ReplyDeleteWe 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 ?
Hi Edwin,
ReplyDeleteWe 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 ?
Hi,
DeleteIndeed 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.
Hi Edwin,
ReplyDeleteWe 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 ?
Hi,
DeleteIn 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
Hi Biemond,
ReplyDeleteI 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
Hi,
DeleteDid you first do an acquire.
Thanks
I have the same issue, Pavan, did you find the reason?
DeleteGreat post!
ReplyDeleteI'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?
Hi,
Deletevery strange, do you have some PPR action going on and do you invoke acquiretask in the pagedef of the page.
Thanks
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
Deleteperforming any other updates. Is there any way to fix with out refreshing the same.
while executing the code, I ma getting below exception in eclipse.
ReplyDeleteoracle.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
Hi,
DeleteI think you need to xmlparvserv2.jar and / or xml.jar located in the oracle_common\modules\oracle.xdk_11.1.0 folder
thanks
Hi Edwin
ReplyDeleteI 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
Hi,
ReplyDeletejust do like me and use OnBehalfOf, create a super user ,authenticaten and this context for OnBehalfOf
taskQueryService.authenticateOnBehalfOf(context, onBehalfOfUser);
Thanks
Hi Edwin,
ReplyDeleteThanks 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
Hi,
DeleteI 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
Hi,
ReplyDeleteI 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.
hi,
ReplyDeleteI 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?
Hi,
ReplyDeleteThanks 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 !
Hi Edwin,
ReplyDeleteGreat 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.
Is there any specific care to be taken to implement this using 12c (12.2.1)?
DeleteUnable to create the "IWorkflowServiceClient" instance. Receving NULL value.