There are different ways to interact with the Human WorkFlow services of the Oracle SOA Suite or BPM. You can use java and use it in your own application, like I did in
this blogpost, use the BPM Worklist application or invoke the Human WorkFlow web services.
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/
TaskService/TaskServicePort?
WSDL
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: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: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: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
To know all the possible
displayColumn values you can decompile the
TableConstants class located in the
oracle.bpel.services.workflow.repos package. Or look at the WF tables in the soa-infra schema.
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: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: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: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/
TaskService/TaskServicePort?
WSDL
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.