In this blogpost I will describe how you can do that and especially how you can query the Human task with your own ordering and restrictions.
You can try these examples from soapUI or any other web service framework / tool.
In this blogpost we will invoke these two WF web services
TaskQueryService, This WS can be used for task retrieval or do a query on the WorkFlow service.
The WSDL url = http://soa-server:8001/integration/services/TaskQueryService/TaskQueryService?WSDL
TaskService, This WS can be used for CRUD actions on the human tasks.
The WSDL url = http://soa-server:8001/integration/services/
Both services got two endpoints, be aware you should always use the endpoint of TaskQueryServicePort and not the SAML port unless you like to use SAML authentication.
<service name="TaskQueryService">
<port name=" TaskQueryServicePortSAML" binding="tns: TaskQueryServiceSOAPBinding">
<soap:address location="http://172.16.0.4: 8001/integration/services/ TaskQueryService/ TaskQueryService2/*"/>
</port>
<port name="TaskQueryServicePort" binding="tns: TaskQueryServiceSOAPBinding">
<soap:address location="http://172.16.0.4: 8001/integration/services/ TaskQueryService/ TaskQueryService"/>
</port>
</service>
When we know our Human TaskId ( something like this 3fa4e9f7-5719-4efa-8215-ad2b47fcbace )
then you can use the getTaskDetailsById operation.
<soapenv:Envelope xmlns:soapenv="http://schemas. xmlsoap.org/soap/envelope/"
xmlns:com="http://xmlns. oracle.com/bpel/workflow/ common">
<soapenv:Header/>
<soapenv:Body>
<tas:taskDetailsByIdRequest>
<com:workflowContext>
<com:credential>
<com:login>weblogic</com: login>
<com:password>weblogic1</com: password>
</com:credential>
</com:workflowContext>
<tas:taskId>3fa4e9f7-5719- 4efa-8215-ad2b47fcbace</tas: taskId>
</tas:taskDetailsByIdRequest>
</soapenv:Body>
</soapenv:Envelope>
In this case I use workflowContext for authentication. You can also do it on behalf of someone else.
Sometimes you only got a Human WorkFlow number then you can use the getTaskDetailsByNumber operation.
<soapenv:Envelope xmlns:soapenv="http://schemas. xmlsoap.org/soap/envelope/"
xmlns:com="http://xmlns. oracle.com/bpel/workflow/ common">
<soapenv:Header/>
<soapenv:Body>
<tas: taskDetailsByNumberRequest>
<com:workflowContext>
<com:credential>
<com:login>weblogic</com: login>
<com:password>weblogic1</com: password>
</com:credential>
</com:workflowContext>
<tas:taskNumber>200000</tas: taskNumber>
</tas: taskDetailsByNumberRequest>
</soapenv:Body>
</soapenv:Envelope>
When you don't know the taskId or the task number or want to do bulk operations then you can do a search on the humantask services. The queryTasks operation is very powerful and there is not really a restriction.
let's start with a simple one. In this request I want to search for a task number and also want to have some extra attributes ( blue part ) in the response together with the Comments, Attachments and the Payloads ( red part ).
<soapenv:Envelope xmlns:soapenv="http://schemas. xmlsoap.org/soap/envelope/"
xmlns:tas="http://xmlns. oracle.com/bpel/workflow/ taskQueryService" \
xmlns:com="http://xmlns. oracle.com/bpel/workflow/ common"
xmlns:tas1="http://xmlns. oracle.com/bpel/workflow/ taskQuery"
<soapenv:Header/>
<soapenv:Body>
<tas:taskListRequest>
<com:workflowContext>
<com:credential>
<com:login>weblogic</com: login>
<com:password>weblogic1</com: password>
</com:credential>
</com:workflowContext>
<tas1:taskPredicateQuery>
<tas1:displayColumnList>
<tas1:displayColumn> textAttribute1</tas1: displayColumn>
<tas1:displayColumn> textAttribute2</tas1: displayColumn>
<tas1:displayColumn> textAttribute3</tas1: displayColumn>
</tas1:displayColumnList>
<tas1:optionalInfoList>
<tas1:taskOptionalInfo> Comments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Attachments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Payload</tas1: taskOptionalInfo>
</tas1:optionalInfoList>
<tas1:predicate>
<tas1:assignmentFilter>All</ tas1:assignmentFilter>
<tas1:clause>
<tas1:column>taskNumber</tas1: column>
<tas1:operator>EQ</tas1: operator>
<tas1:value>200001</tas1: value>
</tas1:clause>
</tas1:predicate>
</tas1:taskPredicateQuery>
</tas:taskListRequest>
</soapenv:Body>
</soapenv:Envelope>In the predicate part we are using the old style for defining our restriction ( clause after predicate ). In the next queryTasks examples I will show the ones which also will be supported in the coming soa suite releases.
assignmentFilter can have the following values: All, My, Group, My+Group, My+Group+All, Reportees, Creator, Owner, Previous, Admin
operator can have the following values: EQ, NEQ, GT, GTE, LT, LTE, LIKE, NOT_LIKE, IN, NOT_IN, CONTAINS, NOT_CONTAINS, BEGINS, NOT_BEGINS, ENDS, NOT_ENDS, BEFORE, AFTER, ON, NEXT_N_DAYS, LAST_N_DAYS, IS_IN_FUTURE, IS_IN_PAST, IS_NULL, IS_NOT_NULL
The optionalInfoList can contain the following values: Actions, GroupActions, CustomActions, Attachments, Comments, Payload, ShortHistory, TemplateTasks
In this query I have a predicate with two clauses which do a search on the text attributes ( tableName attribute is in almost all cases WFTask , check the soa-infa database or the TableConstants class ) and the second one has an AND operator on the first one.
<soapenv:Envelope xmlns:soapenv="http://schemas. xmlsoap.org/soap/envelope/"
xmlns:com="http://xmlns. oracle.com/bpel/workflow/ common"
xmlns:tas1="http://xmlns. oracle.com/bpel/workflow/ taskQuery"
<soapenv:Header/>
<soapenv:Body>
<tas:taskListRequest>
<com:workflowContext>
<com:credential>
<com:login>weblogic</com: login>
<com:password>weblogic1</com: password>
</com:credential>
</com:workflowContext>
<tas1:taskPredicateQuery startRow="1" endRow="10">
<tas1:displayColumnList>
<tas1:displayColumn> textAttribute1</tas1: displayColumn>
<tas1:displayColumn> textAttribute2</tas1: displayColumn>
<tas1:displayColumn> textAttribute3</tas1: displayColumn>
</tas1:displayColumnList>
<tas1:optionalInfoList>
<tas1:taskOptionalInfo> Comments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Attachments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Payload</tas1: taskOptionalInfo>
</tas1:optionalInfoList>
<tas1:predicate>
<tas1:assignmentFilter>All</ tas1:assignmentFilter>
<tas1:predicate>
<tas1:clause>
<tas1:column tableName="WFTask">
<tas1:columnName> textAttribute1</tas1: columnName>
</tas1:column>
<tas1:operator>EQ</tas1: operator>
<tas1:value>MyTask</tas1: value>
</tas1:clause>
<tas1:clause joinOperator="AND">
<tas1:column tableName="WFTask">
<tas1:columnName> textAttribute2</tas1: columnName>
</tas1:column>
<tas1:operator>EQ</tas1: operator>
<tas1:value>1234</tas1:value>
</tas1:clause>
</tas1:predicate>
</tas1:predicate>
</tas1:taskPredicateQuery>
</tas:taskListRequest>
</soapenv:Body>
</soapenv:Envelope>
In the next example we will add some ordering and use a valuelist in a predicate clause ( for this we need to use the IN operator).
<soapenv:Envelope xmlns:soapenv="http://schemas. xmlsoap.org/soap/envelope/"
xmlns:com="http://xmlns. oracle.com/bpel/workflow/ common"
xmlns:tas1="http://xmlns. oracle.com/bpel/workflow/ taskQuery"
<soapenv:Header/>
<soapenv:Body>
<tas:taskListRequest>
<com:workflowContext>
<com:credential>
<com:login>weblogic</com: login>
<com:password>weblogic1</com: password>
</com:credential>
</com:workflowContext>
<tas1:taskPredicateQuery>
<tas1:displayColumnList>
<tas1:displayColumn> textAttribute1</tas1: displayColumn>
<tas1:displayColumn> textAttribute2</tas1: displayColumn>
<tas1:displayColumn> textAttribute3</tas1: displayColumn>
</tas1:displayColumnList>
<tas1:optionalInfoList>
<tas1:taskOptionalInfo> Comments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Attachments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Payload</tas1: taskOptionalInfo>
</tas1:optionalInfoList>
<tas1:predicate>
<tas1:assignmentFilter>My+ Group</tas1:assignmentFilter>
<tas1:predicate>
<tas1:clause>
<tas1:column tableName="WFTask">
<tas1:columnName>state</tas1: columnName>
</tas1:column>
<tas1:operator>IN</tas1: operator>
<tas1:valueList>
<tas1:value>ASSIGNED</tas1: value>
<tas1:value>INFO_REQUESTED</ tas1:value>
<tas1:value>OUTCOME_UPDATED</ tas1:value>
</tas1:valueList>
</tas1:clause>
</tas1:predicate>
</tas1:predicate>
<tas1:ordering>
<tas1:clause>
<tas1:column>priority</tas1: column>
<tas1:table>WFTask</tas1: table>
<tas1:sortOrder>ASCENDING</ tas1:sortOrder>
<tas1:nullFirst>false</tas1: nullFirst>
</tas1:clause>
<tas1:clause>
<tas1:column>taskNumber</tas1: column>
<tas1:table>WFTask</tas1: table>
<tas1:sortOrder>DESCENDING</ tas1:sortOrder>
<tas1:nullFirst>false</tas1: nullFirst>
</tas1:clause>
</tas1:ordering>
</tas1:taskPredicateQuery>
</tas:taskListRequest>
</soapenv:Body>
</soapenv:Envelope>
For the Ordering I need to provide the column and table values ( table element is in almost all cases WFTask , check the soa-infa database or the TableConstants class )
The last query task has a more complex predicate, for this we need to use lhs , logicalOperator and rhs elements. And the rhs element contains an another lhs , logicalOperator and rhs section.
<soapenv:Envelope xmlns:soapenv="http://schemas. xmlsoap.org/soap/envelope/"
xmlns:com="http://xmlns. oracle.com/bpel/workflow/ common"
xmlns:tas1="http://xmlns. oracle.com/bpel/workflow/ taskQuery"
<soapenv:Header/>
<soapenv:Body>
<tas:taskListRequest>
<com:workflowContext>
<com:credential>
<com:login>weblogic</com: login>
<com:password>weblogic1</com: password>
</com:credential>
</com:workflowContext>
<tas1:taskPredicateQuery startRow="1" endRow="10">
<tas1:displayColumnList>
<tas1:displayColumn> textAttribute1</tas1: displayColumn>
<tas1:displayColumn> textAttribute2</tas1: displayColumn>
<tas1:displayColumn> textAttribute3</tas1: displayColumn>
</tas1:displayColumnList>
<tas1:optionalInfoList>
<tas1:taskOptionalInfo> Comments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Attachments</tas1: taskOptionalInfo>
<tas1:taskOptionalInfo> Payload</tas1: taskOptionalInfo>
</tas1:optionalInfoList>
<tas1:predicate>
<tas1:assignmentFilter>My+ Group</tas1:assignmentFilter>
<tas1:predicate>
<tas1:lhs>
<tas1:clause>
<tas1:column tableName="WFTask">
<tas1:columnName>state</tas1: columnName>
</tas1:column>
<tas1:operator>IN</tas1: operator>
<tas1:valueList>
<tas1:value>ASSIGNED</tas1: value>
<tas1:value>INFO_REQUESTED</ tas1:value>
<tas1:value>OUTCOME_UPDATED</ tas1:value>
</tas1:valueList>
</tas1:clause>
</tas1:lhs>
<tas1:logicalOperator>AND</ tas1:logicalOperator>
<tas1:rhs>
<tas1:lhs>
<tas1:clause>
<tas1:column tableName="WFTask">
<tas1:columnName> textAttribute1</tas1: columnName>
</tas1:column>
<tas1:operator>EQ</tas1: operator>
<tas1:value>MyTask</tas1: value>
</tas1:clause>
<tas1:clause joinOperator="AND">
<tas1:column tableName="WFTask">
<tas1:columnName> textAttribute2</tas1: columnName>
</tas1:column>
<tas1:operator>EQ</tas1: operator>
<tas1:value>1234</tas1:value>
</tas1:clause>
</tas1:lhs>
<tas1:logicalOperator>OR</ tas1:logicalOperator>
<tas1:rhs>
<tas1:clause>
<tas1:column tableName="WFTask">
<tas1:columnName> textAttribute2</tas1: columnName>
</tas1:column>
<tas1:operator>EQ</tas1: operator>
<tas1:value>123</tas1:value>
</tas1:clause>
</tas1:rhs>
</tas1:rhs>
</tas1:predicate>
</tas1:predicate>
</tas1:taskPredicateQuery>
</tas:taskListRequest>
</soapenv:Body>
</soapenv:Envelope>
At last we can also try update a Task with a particular outcome. For this we need to use the TaskService
http://soa-server:8001/integration/services/
Use the right endpoint ( not the SAML one ) and use the operation updateTaskOutcome ( this is the easiest way )
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tas="http://xmlns.oracle.com/bpel/workflow/taskService"
xmlns:com="http://xmlns.oracle.com/bpel/workflow/common"
xmlns:task="http://xmlns.oracle.com/bpel/workflow/task"
xmlns:tas1="http://xmlns.oracle.com/bpel/workflow/TaskEvidenceService">
<soapenv:Header/>
<soapenv:Body>
<tas:updateTaskOutcome>
<com:workflowContext>
<com:credential>
<com:login>humantask</com:login>
<com:password>Welcome01</com:password>
</com:credential>
</com:workflowContext>
<tas:taskId>3e80842f-75c9-4e3d-b441-a7f339df4109</tas:taskId>
<tas:outcome>OK</tas:outcome>
</tas:updateTaskOutcome>
</soapenv:Body>
</soapenv:Envelope>
Just provide the taskId and what the outcome should be.
Hi Edwin, the end point /integration/services/TaskQueryService/TaskQueryServicePort?WSDL gives a 404 error for me.
ReplyDelete/integration/services/TaskQueryService/TaskQueryService?WSDL is available but I get :
...
ns0:InvalidSecurity
InvalidSecurity : error in processing the WS-Security security header
...
Is this the SAML issue?
Mark
Hi,
DeleteDo you get this error in soapui when invoking a request or with loading the wsdl.
in soapui you can change the endpoint on the top of the request.
thanks
Thanks for your response. I managed to get the service working. I think my problem was not calling the authenticate service first and using the token passed back in subsequent calls.
DeleteSuccessful payload for me;
a075f524-53ef-4713-82e7-0145ad3853bf;;i1sDxUH6FW/5af/QlrBMDlOdu8YG65+CfbSd0fMpkOfZWUHxdUwEsV6LM3gH8c3Ic1kSNT17LPxp8kOO6uZ1LQAy2zrwa5mX9e08I01Cp8RjIPnB0k8idpIt21+Pv+tS7xsEeNBHWhASDszU/pzZONbKcYsu1auQmTEMw0iEnuCrP5PWa8t8iar/vg3CdxSCPFhhQVcNUHjAoQaIJB2ppGu7+sFyHrBPwM/TCLwsz0udQXEOT+h4uLoy/5v0uiDg
All
State
EQ
ASSIGNED
Note I could not access the endpoint .../TaskQueryServicePort?WSDL you mentioned so I'm using /TaskQueryService?WSDL We are running SOA suite 11.1.1.4.
Thanks Mark
Hi,
DeleteI also running PS3 and everything is working fine and I don't need a token. just can use username / password
Also both wsdl url are working on PS3.
TaskQueryService, This WS can be used for task retrieval or do a query on the WorkFlow service.
The WSDL url = http://soa-server:8001/integration/services/TaskQueryService/TaskQueryService?WSDL
TaskService, This WS can be used for CRUD actions on the human tasks.
The WSDL url = http://soa-server:8001/integration/services/TaskService/TaskServicePort?WSDL
thanks
Edwin, are you able to get the getDisplayURL() method to work for the TaskQueryService?
ReplyDeleteVivek
Hi,
DeleteWhat is getDisplayURL , is that an wsdl operation
thanks
Sorry, I meant to ask this in relation to a task obtained using getTaskDetailsById or getTaskDetailsByNumber. All task details area available except for task.getDisplayURL().
DeleteI think it is a fixed url with a taskId parameter.
Deleteyou can check it in the EM instance process when you click on the humantask. it will give you a direct link to the worklist app.
thanks
I agree its a fixed URL...comes from the WorkFlowUtil class. The question is: should the task api which has this method return a fixed url.
DeleteI can check EM and get the URL. How does one solve this problem in code when a random task has to be opened?
Thanks
Vivek
Hi Edwin,
ReplyDeleteI am using BPEL human task API - createTask/initiateTask API in particular to create a new task. I am able to do this. Now I am trying to create a task with multiple owners - tried this using the setOwner() method on Task object and also tried comma separated owners through the payload - Both does not seem to work :(.
Hi,
Deleteyou can assign to multiple groups or users but I think there can only be one process owner.
thanks
It is really nice and informative, it is useful for me. thank you
ReplyDeleteHi Edwin,
ReplyDeletedid you ever try to initiate a task via the "initiateTask" web service operation?
I think I'm missing something here: I'm able to create (and submit) an initiate task instance this way, but here is no (SCA) process instance created for this task.
In addition, this works without providing credentials (as you have to do in all the other operations).
<soapenv:Envelope ...>
<soapenv:Header/>
<soapenv:Body>
<tas:initiateTask>
<task:task>
<task:title>My Task, just created</task:title>
<task:payload></task:payload>
<task:priority>3</task:priority>
<task:taskDefinitionURI>default/SimpleBPM!1.0/Humantask1</task:taskDefinitionURI>
<task:creator>weblogic</task:creator>
<task:ownerUser>weblogic</task:ownerUser>
</task:task>
</tas:initiateTask>
</soapenv:Body>
Hi,
DeleteI never, always use it with BPEL so I can react on the outcome. Initiate without bpel only works I guess in the Worklist application and in combination with BPM where WF is the starting of a process.
thanks
Hi Edwin,
ReplyDeleteDo you know if the Task Title can be updated?
Thanks,
Vivek
Hi,
DeleteI think it should be possible , you can assign it to a payload variable when you create the HWF from BPEL or try to use the TaskService WS/ EJB
thanks
Hi Edwin,
DeleteThanks a lot for the reply.
I tried both the approaches:
- Assigning a payload variable to the title did give me the correct title after the task was initiated. However, after that when the payload variable changed (using the updateTask WS call), the task title remained the same.
- When I tried to change the Title directly using the WS call, it did not update (other attributes like priority were updated successfully).
Is there anything else I can try?
Thanks for the help,
Vivek
Hi,
DeleteI think you tried it all , maybe you can ask for a SR or ER on oracle support.
thanks
By the way,
Deletenot supported by Oracle , all data is in the WF Tasks table , find the right row with the task id as primary key and update the title.
Thanks Edwin, will try out that suggestion.
DeleteAn unrelated question: What can I do so that weekends are ignored for for expiration? Do I need to create a new Calendar Rule in BPM workspace? Is there any other way?
Thanks,
Vivek
Hi Edwin,
ReplyDeleteWith Regards to Task Title, a DB update on the WFTask_TL title worked.
Thanks a ton for the tip.
- Vivek
Biemond Hello, I can not introspect the WSDL http://host:port/integration/services/TaskService/TaskServicePort?WSDL in jdev 11.1.1.6 (PS5). The endpoint is pointing to SOA 11.1.1.6 (PS5).
ReplyDeleteBut I can introspect the same endpoint in jdev 11.1.1.5 (PS4). Seems to be a product problem. Know it?
I´m using Windows 7 O.S.
DeleteHi,
DeleteFor the Task and TaskQuery Services (PS5) I had to patch the soa suite. there were some problems with the workflow xsd in jdeveloper and on the server. I had to use the patch the fabric runtime jar on the server and in jdeveloper.
thanks.
Hi Edwin,
ReplyDeleteThe post is very useful and informative.Could you please let me know how can we use the SAML configuration for these webservices.
Thanks
Hi,
DeleteThen you need to follow this http://biemond.blogspot.nl/2011/08/do-saml-with-owsm.html
So make osb business service or soa reference service with an owsm saml client policy and call the saml endpoint , on the proxy or soa service side use a username token policy, call this service and add your credentials and this will passed on to the human workflow services.
Thanks
Thanks