Skip Headers
Oracle® Fusion Applications Developer's Guide
11g Release 1 (11.1.1.5)

Part Number E15524-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

43 Managing Tasks Programmatically

When to implement: When you need to programmatically create, set an outcome for, or query task information that resides in one or more SOA domains.

Design Pattern Summary: The design pattern involves programmatic interaction with human task client services by an application with the following requirements: displaying task status information, providing UI facets to enable setting task outcomes without navigating through the worklist, and submitting new tasks without initiating a BPEL process.

In addition, the human task services support federated task queries across several SOA domains so as to obtain an aggregated task list across several product families.

Involved components:

43.1 Introduction to the Recommended Design Pattern

Some Oracle Fusion web applications have use cases that require programmatically interacting with the human workflow layer to approve, reject and display lists of tasks using specific search criteria. All SOA runtime environments that are configured as part of the topology are stored in the Oracle Fusion Middleware Extensions for Applications taxonomy schema and accessed at runtime using APIs. In the taxonomy schema, each SOA runtime environment has an entry with a unique identifying name that maps to a corresponding endpoint URL. For example, a SOA runtime environment called FIN_SOA_RMI has a corresponding endpoint URL t3://fpp-02.mycompany.com:7001/.

At runtime, the taxonomy schema is queried to construct a list of servers and their respective endpoints. This list of servers and endpoints passes to the human workflow client service APIs as a JAXB object. In the context of the federated task query service, some or all of these servers can be referenced. One of these servers is set as the default, and is used in the context of non-federated task services such as the task and task query services.

Alternatively, servers can be excluded from the list of federated servers, and exist only in the JAXB object. This allows servers to be used only when named explicitly in the list of requested servers. In this case, the excluded servers will not be used when the list of requested servers is empty.

Oracle Fusion Middleware Extensions for Applications maintains the list of servers in the taxonomy tables. An API enables building the JAXB object based on the list of SOA domains in the Oracle Fusion Applications topology.

This pattern is recommended as it provides the following features:

43.2 Potential Approaches

43.3 Example

The Expenses team has an Expenses Manager role with administrator privileges to approve or reject expenses that belong to other users. The Expenses team must provide a workbench that collectively scans all SOA domains for open expense notifications and provide a consolidated UI to set their outcome, potentially all at once. This UI would comprise a table listing notifications matching certain filter criteria with buttons to select and set the appropriate outcome of the expense. This is done through RMI interaction with the appropriate SOA domain.

43.4 Managing Human Workflow Tasks from a Java Application

These are two main high-level steps involved in this process:

43.4.1 How to Connect to the Task Service/Task Query Service

The human workflow APIs provide three types of task services: single, query and federated query. The type of service you use depends on the product use case. The RMI endpoint for these services must be derived at runtime and compiled into a server list. The server list is contained by a JAXB object, which can be passed to the human workflow client service APIs. In order to support this runtime lookup, the Oracle Fusion Middleware Extensions for Applications taxonomy schema and APIs must be seeded during provisioning. You need only provide an ArrayList (java.util.ArrayList) of server names to be used in the federated query.

Note:

Consider performance requirements when using the query or federated query service APIs. It is recommended to page the result sets in batches, for example, in sets of 10-25.

Services are as follows:

  • Task Service: The task service programmatically sets a task outcome, such as approve or reject for a single, particular task using a single, particular SOA runtime.

  • Task Query Service: The task query service programmatically queries tasks for a particular task type. Use the portlet to render a worklist and relevant tasks in your dashboard. Alternatively, you may manually build the worklist instead.

  • Federated Task Query Service: The federated task query service programmatically executes a federated query of tasks for a particular task type. Use the portlet to render a worklist and relevant tasks in your dashboard. Alternatively, you may manually build the worklist instead.

Use the following guidelines to determine the type of task or query service to use.

  • Single server task service API: Use this API to obtain a single task object using the task number or task ID from a single, specific SOA runtime.

  • Single server task query service API: Use this API to query for tasks from a single, specific SOA runtime.

  • Federated task query service API: Use this API to query tasks based on namespace or task name from one or more SOA runtime domains.

43.4.2 How to Use the Single Server Task Service API

If your use case requires connecting to one SOA domain and obtaining the details of a single task via a primary key such as task number or task ID, take the following steps. Once obtained, configure the task detail display or set the task outcome.

  • Import libraries into the Java project.

  • Import code packages into the Java project.

  • Declare and obtain task service object references.

43.4.2.1 Import Libraries into the Java Project

Add the following libraries to the Oracle JDeveloper project:

  • Applications Core: Add this library to enable using Oracle Fusion Middleware Extensions for Applications taxonomy APIs to obtain the necessary JAXB object containing the RMI endpoint information for the desired server.

  • SOA Runtime: Add this library to enable using the human workflow task query APIs.

43.4.2.2 Import Code Packages into the Java Project

Import the code packages shown in Example 43-1 into the Java source.

Example 43-1 Importing Code Packages to Enable Using the Single Server Task Service API

import java.util.ArrayList;
import java.util.List;
 
import java.util.logging.Logger;
 
import javax.jws.WebService;
 
import oracle.bpel.services.workflow.verification.IWorkflowContext;
import oracle.bpel.services.workflow.client.IWorkflowServiceClient;
import oracle.bpel.services.workflow.task.model.Task;
 
import oracle.bpel.services.workflow.IWorkflowConstants;
import oracle.bpel.services.workflow.client.WorkflowServiceClientFactory;
import oracle.bpel.services.workflow.query.ITaskQueryService;
import oracle.bpel.services.workflow.repos.Ordering;
import oracle.bpel.services.workflow.repos.Predicate;
import oracle.bpel.services.workflow.repos.TableConstants;
import oracle.bpel.services.workflow.task.IInitiateTaskResponse;
import oracle.bpel.services.workflow.task.ITaskService;
import oracle.bpel.services.workflow.task.model.ObjectFactory;
 
import oracle.apps.fnd.applcore.common.DeploymentsUtil;
 
import oracle.bpel.services.workflow.client.config.RemoteClientType;
import oracle.bpel.services.workflow.client.config.ServerType;
import oracle.bpel.services.workflow.client.config.WorkflowServicesClientConfigurationType;

43.4.2.3 Declare and Obtain Task Service Object References

Create the query and task service references by invoking the WorkflowServiceClientFactory API getWorkflowServiceClient method, which provides the JAXB object containing the server list and a logger object reference. The human workflow task service connects to the server marked as the default in the JAXB object. When calling the APIs to craft the JAXB object, be sure to specify the name of the server you want to call. Example 43-2 shows sample code used to declare and obtain task service object references.

Example 43-2 Declaring and Obtaining Task Service Object References

ITaskService taskSvc = null;
        ITaskQueryService querySvc = null;
        IWorkflowContext wfCtx = null;
        java.util.logging.Logger logger = Logger.getLogger("oracle.apps");
        try {
            WorkflowServicesClientConfigurationType wscct = 
                   getWorkflowClientConfigObject("FIN_SOA_RMI);
            if ( wscct == null ) {  //Log incident
                return "FAILED!";
            } // if
 
            IWorkflowServiceClient wfSvcClient = 
                 WorkflowServiceClientFactory.getWorkflowServiceClient(wscct, logger);
            taskSvc = wfSvcClient.getTaskService();
            querySvc = wfSvcClient.getTaskQueryService();

Note:

Previously, developers would populate the properties for EJB_PROVIDER and EJB_SECURITY to provide the RMI endpoint and credentials. Instead, RMI identity propagation uses the current user context for authentication. In Oracle Fusion Applications, most UI and services require authentication that provides the appropriate user context. If no current user context exists, create one.

43.4.2.4 Obtain the Workflow Service Context Object

In order to sustain performance in all interactions to the workflow client service APIs, pass the workflow service context object to any applicable APIs. To obtain the context using the current user's identity, call the getWorkflowContextForAuthenticatedUser() method, as shown in Example 43-3.

Example 43-3 Getting the Workflow Service Context Object

// Get the workflow task service context for use in later calls for performance 
// improvement
wfCtx = querySvc.getWorkflowContextForAuthenticatedUser();

Note:

For performance reasons, be sure to pass this context to all subsequent calls to the APIs.

43.4.2.5 Obtain the Single Task Object and Set Task Outcome

When interacting with the task service, you must first obtain the task number or ID for the task in order to retrieve the task details. Use the task number or task ID to invoke the getTaskDetailsById or getTaskDetailsByNumber methods of the task query service object.

Note:

This approach assumes that you have obtained the task number or task ID (either through the task query service or otherwise).

Example 43-4 shows the approval of a task with the ID 0a6d287a-9849-4e5e-914b-805706d6b9d9.

Example 43-4 Getting the Single Task Object with the Task ID

Task t = querySvc.getTaskDetailsById(wfCtxt, "0a6d287a-9849-4e5e-914b-805706d6b9d9");
taskSvc.updateTaskOutcome(wfCtxt, t, "APPROVE");
// Another example, using the task number to reject a task.
Task t = querySvc.getTaskDetailsByNumber(wfCtxt, 200140 );
taskSvc.updateTaskOutcome(wfCtxt, t, "REJECT");

Example 43-5 shows how to use STDOUT calls to display the various task attributes through the task API.

Example 43-5 Using STDOUT Calls to Display Task Attributes

System.out.println("Task Number: " + task.getSystemAttributes().getTaskNumber());
System.out.println("Task Id: " + task.getSystemAttributes().getTaskId());
System.out.println("Titl    e: " + task.getTitle());
System.out.println("Priority: " + task.getPriority());
System.out.println("State: " + task.getSystemAttributes().getState());

43.4.3 How to Use the Single Server Task Query Service API

If your use case involves connecting to a single SOA domain and querying for all tasks that match certain criteria, take the following steps. Once you have queried for the relevant tasks, you can display them in an ordered list in the UI or programmatically set task outcome all at once.

  • Import libraries into the Java project.

  • Import code packages into the Java project.

  • Declare and obtain task query service object references.

  • Manage query and task outcome states.

43.4.3.1 Import Libraries into the Java Project

Import the libraries described in Section 43.4.2.1, "Import Libraries into the Java Project."

43.4.3.2 Import Code Packages into the Java Project

Import the code packages described in Section 43.4.2.2, "Import Code Packages into the Java Project."

43.4.3.3 Declare and Obtain Task Query Service Object References

Create the query and task service references by invoking the WorkflowServiceClientFactory API getWorkflowServiceClient method, which provides the JAXB object containing the server list and a logger object reference. The human workflow task service connects to the server marked as the default in the JAXB object. When calling the APIs to craft the JAXB object, be sure to specify the name of the server you want to call.

Example 43-6 shows sample code in which task query service object references are declared and obtained.

Example 43-6 Declaring and Obtaining Task Query Service Object References

ITaskService taskSvc = null;
ITaskQueryService querySvc = null;
IWorkflowContext wfCtx = null;
try {
     java.util.logging.Logger logger = Logger.getLogger("oracle.apps");
     WorkflowServicesClientConfigurationType wscct =
        getWorkflowClientConfigObject("FIN_SOA_RMI);
if ( wscct == null )   {               // Log incident
 return "FAILED!";            }
} 

IWorkflowServiceClient wfSvcClient =
WorkflowServiceClientFactory.getWorkflowServiceClient(wscct, logger);
taskSvc = wfSvcClient.getTaskService();
querySvc = wfSvcClient.getTaskQueryService();

Note:

Previously, developers would populate the properties for EJB_PROVIDER and EJB_SECURITY to provide the RMI endpoint and credentials. Instead, RMI identity propagation uses the current user context for authentication. In Oracle Fusion Applications, most UI and services require authentication that provides the appropriate user context. If no current user context exists, create one.

43.4.3.4 Manage Query and Task Outcome States

Performing queries and interacting with the task result set is similar for both the federated and non-federated task query services. For more information about this process, see Section 43.4.5, "How to Query and Traverse Federated and Non-federated Query Result Sets."

43.4.4 How to Use the Federated Server Task Query Service API

Using the federated server task query service API involves the following main steps:

  • Import libraries into the Java project.

  • Import code packages into the Java project.

  • Create a list of servers for a parallel federated query.

  • Declare task and query service references, and create the workflow client service object.

  • Obtain the workflow service client.

  • Implement exception handling for federated queries.

  • Manage query and task outcome states.

43.4.4.1 Import Libraries into the Java Project

Import the libraries described in Section 43.4.2.1, "Import Libraries into the Java Project."

43.4.4.2 Import Code Packages into the Java Project

Import the code packages described in Section 43.4.2.2, "Import Code Packages into the Java Project."

In addition, import the code package shown in Example 43-7.

Example 43-7 Importing the Code Package IFederatedWorkflowContext

import oracle.bpel.services.workflow.fws.client.IFederatedWorkflowContext;

43.4.4.3 Create a List of Servers for a Parallel Federated Query

To leverage the federated query service, decide whether to query all human workflow services in Oracle Fusion Applications or just a subset of those services. The servers are named according to standards and are populated in a JAXB object which contain the service endpoints for lookup at runtime. You need only know the name or names of the product services you want to poll or provide a list

To use a subset of the human workflow services, construct a Java list of those service names and pass that list to getFederatedTaskQueryService.

Note:

Be sure to provide a list of requested servers, as all servers in the list are polled. Failing to provide a list of servers results in all the servers being polled, which has significant performance implications.

Example 43-8 shows sample code in which a list of servers is created for a parallel federated query.

Example 43-8 Creating a List of Servers for a Parallel Federated Query

// Create the human workflow server subset list.
List<String> requestedServers  =  new ArrayList<String>();
requestedServers .add("FIN_SOA_RMI");
requestedServers .add("CRM_SOA_RMI ");
requestedServers .add("PRJ_SOA_RMI");

43.4.4.4 Declare Task and Query Service References and Create the Workflow Client Service Object

After constructing the server list, obtain the query service object reference by invoking the getFederatedTaskQueryService API of the WorkflowServiceClientFactory, as shown in Example 43-9.

Example 43-9 Declaring Task and Query Service References and Creating the Workflow Client Service Object

java.util.logging.Logger logger = Logger.getLogger("oracle.apps");
WorkflowServicesClientConfigurationType wscct =
  getWorkflowClientConfigObject("FIN_SOA_RMI");
if ( wscct == null ) {    // Log Incident
   return "FAILED!";
 }// if
querySvc = WorkflowServiceClientFactory.getFederatedTaskQueryService(wscct, requestedServers, logger);

Note:

Previously, developers would populate the properties for EJB_PROVIDER and EJB_SECURITY to provide the RMI endpoint and credentials. Instead, RMI identity propagation uses the current user context for authentication. In Oracle Fusion Applications, most UI and services require authentication that provides the appropriate user context. If no current user context exists, create one.

43.4.4.5 Obtain the Workflow Service Context

Obtain the workflow service context from the query service, as shown in Example 43-10. This improves performance with all workflow client service API interactions.

Example 43-10 Obtaining the Workflow Service Context

fedWFCtx = (IFederatedWorkflowContext) querySvc.getWorkflowContextForAuthenticatedUser();

Note:

This context is cast as IFederatedWorkflowContext. For performance reasons, the context must be passed to all subsequent API calls.

43.4.4.6 Implement Exception Handling for Federated Queries

When performing queries on federated task query services, exceptions in communicating with any servers in the list of servers do not cause the query to fail. Instead, the context has a boolean isFailed() operation which can be interrogated to determine whether any failures occurred. Exceptions can be obtained from the context's getExceptionMap() method as shown in Example 43-11.

Example 43-11 Implementing Exception Handling

// Partial success does not throw exceptions, instead check for isFailed and
// inspect the Exception and Context maps.
if ( fedWFCtx.isFailed() ) {
    // Log Messages
    logger.warning("Exception map: " + fedWFCtx.getExceptionMap());
    logger.warning("Contextmap: " + fedWFCtx.getWorkflowContextMap());
} // if

43.4.4.7 Manage Query and Task Outcome States

Performing queries and interacting with the task result set is similar for both the federated and non-federated task query services. For more information about this process, see Section 43.4.5, "How to Query and Traverse Federated and Non-federated Query Result Sets."

43.4.5 How to Query and Traverse Federated and Non-federated Query Result Sets

Querying and traversing federated and non-federated query result sets involves the following main steps:

  • Determine query service search criteria.

  • Construct the predicate for the queryTasks() method.

  • Arrange the order of results returned by the queryTasks() method.

  • Construct the list of display columns for the queryTasks() method.

  • Construct a list of OptionalInfo items for the results of the queryTasks() method.

  • Invoke the queryTasks() method with the attribute lists.

  • Iterate through the result set.

  • Programmatically set the task outcome.

43.4.5.1 Determine Query Service Search Criteria

This section assumes you have implemented the task query service for either single or federated queries by following the instructions in Section 43.4.3, "How to Use the Single Server Task Query Service API" and Section 43.4.4, "How to Use the Federated Server Task Query Service API."

For example, creating a human task in a composite produces a TASK file containing the metadata that defines the task behavior for approval hierarchy as well as possible outcomes. Examining the source of this TASK file reveals the task name, target namespace, possible outcomes, and so on. When deploying the composite containing this task, the WFTASK tables are updated with task-related data that supports the human workflow infrastructure, as shown in Example 43-12.

Example 43-12 Sample *.task File Snippet

<?xml version = '1.0' encoding = 'UTF-8'?>
<taskDefinition targetNamespace="http://xmlns.oracle.com/WFClientPatternSOAApp/WFClientPatternTaskComposite/Humantask1"
xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
xmlns:ora="http://schemas.oracle.com/xpath/extension"
xmlns:orcl="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
xmlns:task="http://xmlns.oracle.com/bpel/workflow/task"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://xmlns.oracle.com/bpel/workflow/taskDefinition"
xmlns:evidence="http://xmlns.oracle.com/bpel/workflow/TaskEvidenceService"
xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue"
xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
xmlns:ns0="http://xmlns.oracle.com/bpel/workflow/common"
xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath"
xmlns:tsc="http://xmlns.oracle.com/bpel/workflow/common/tsc"
xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"
xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath"
xmlns:mhdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.mediator.service.common.functions.GetRequestHeaderExtnFunction">
<name>Humantask1</name>
...

The task metadata includes a value for targetNamespace, in this case http://xmlns.oracle.com/WFClientPatternSOAApp/WFClientPatternTaskComposite/Humantask1.

If you can access the SOAInfra schema of your runtime environment, you can query the details of this task with the query shown in Example 43-13.

Example 43-13 Query task details

select * from wftaskmetadata where namespace = 'http://xmlns.oracle.com/WFClientPatternSOAApp/WFClientPatternTaskComposite/Humantask1';

This query results in the WFTASKMETADATA row, shown in Table 43-1 and Table 43-2.

Table 43-1 WFTASKMETADATA Row Part One

ID URI Name Title Component Name

default/SOAComposite1!1.0*2008-12-02_08-32-41_642/Humantask1

default/SOAComposite1!1.0*2008-12-02_08-32-41_642/Humantask1

Humantask1

string('Task TItle')

Humantask1


Table 43-2 WFTASKMETADATA Row Part Two

CompositeDN CompositeName Composite Version Namespace

default/SOAComposite1!1.0*2008-12-02_08-32-41_642

SOAComposite1

1.0

http://xmlns.oracle.com/WFClientPatternSOAApp/WFClientPatternTaskComposite/Humantask1&nbsp


You can then query the WFTASK table using the task ID shown in the first column of Table 43-1, as shown in Example 43-14.

Example 43-14 Query the WFTASK table using the task ID

task:select * from wftask where taskdefinitionid = 'default/SOAComposite1!1.0*2008-12-02_08-32-41_642/Humantask1';

The results of the entire table are too large to print, but the selected columns shown in Table 43-3 may be useful.

Table 43-3 Useful Columns

Column Name Column Value

State

ASSIGNED

TaskID

0a6d287a-9849-4e5e-914b-805706d6b9d9

TaskNumber

200140

WorkflowDescriptorURI

default/SOAComposite1!1.0*2008-12-02_08-32-41_642/Humantask1

TaskDefinitionID

default/SOAComposite1!1.0*2008-12-02_08-32-41_642/Humantask1

TaskDefinitionName

Humantask1

CorrelationID

0a6d287a-9849-4e5e-914b-805706d6b9d9


This example focuses on tasks belonging to the current user identity, obtained automatically from the session context and passed using a SAML token in the SOAP header. These tasks that bear the ASSIGNED state and match the namespace http://xmlns.oracle.com/WFClientPatternSOAApp/WFClientPatternTaskComposite/Humantask1.

43.4.5.2 Construct the Predicate for queryTasks()

Predicate construction is the instantiation of objects which define an expression to model the conditional part of the underlying where clause. For example, a conditional statement such as TASKNUMBER = 200140 equates to the predicate constructor shown in Example 43-15.

Example 43-15 Constructing the Predicate

new Predicate(TableConstants.WFTASK_TASKNUMBER_COLUMN, Predicate.OP_EQ, 200140);

For this case, a predicate is required to match the WFTASKMETA_NAMESPACE_COLUMN and the WFTASK_STATE_COLUMN columns to the appropriate values. First create the namespace column predicate, then the state column predicate, followed by a predicate combining these two predicates with a conditional, as shown in Example 43-16.

Example 43-16 Creating Namespace, State and Combination Predicates

Predicate predicate1 = new Predicate(TableConstants.WFTASK_STATE_COLUMN, Predicate.OP_EQ, IWorkflowConstants.TASK_STATE_ASSIGNED);
Predicate predicate2 = new Predicate(TableConstants.WFTASKMETADATA_NAMESPACE_COLUMN, Predicate.OP_EQ, TASK_TARGET_NAMESPACE );
Predicate predicate = new Predicate(predicate1, Predicate.AND, predicate2);

An additional way to construct a predicate is shown in Example 43-17, as specified in the ITaskQueryService documentation.

Example 43-17 Another Way to Construct a Predicate

Predicate statePredicate = new Predicate(TableConstants.WFTASK_STATE_COLUMN, Predicate.OP_NEQ, IWorkflowConstants.TASK_STATE_ASSIGNED);
statePredicate.addClause(Predicate.AND, TableConstants.WFTASK_NUMBERATTRIBUTE1_COLUMN, Predicate.OP_IS_NULL, nullParam);
Predicate datePredicate = new Predicate(TableConstants.WFTASK_ENDDATE_COLUMN, Predicate.OP_ON, new Date());
Predicate predicate = new Predicate(statePredicate, Predicate.AND, datePredicate);

43.4.5.3 Arrange the Order of Results Returned by the queryTasks() Method

This step is optional.

The Ordering parameter facilitates implementing an ORDER_BY clause in the task list query.

In Example 43-18, the TITLE_COLUMN and PRIORITY_COLUMN properties are added to the ORDER_BY clause.

Example 43-18 Constructing the Ordering of queryTasks()

// Create the ordering
Ordering ordering = new Ordering(TableConstants.WFTASK_TITLE_COLUMN, true, true);       
ordering.addClause(TableConstants.WFTASK_PRIORITY_COLUMN, true, true);

43.4.5.4 Construct the List of Display Columns for the queryTasks() Method

By default, the queryTasks() method returns only a list of tasks with their TASKID value. If you require additional columns, such as TASKNUMBER, TITLE, PRIORITY, STATE, ENDDATE, ASSIGNEE, COMPOSITEINSTANCEID, ROOTTASKID, and so on, construct an ArrayList of String objects containing the names of the additional columns you want returned in the result set. Example 43-19 shows sample code that constructs a list of display columns for queryTasks().

Example 43-19 Constructing the List of Display Columns for queryTasks()

// List of display columns
// For those columns that are not specified here, the queried Task object will not
// hold any value.
// For example: If TITLE is not specified, task.getTitle() returns a value of
// null.
// For the list of most comonly used columns, check the table below
// Note: TASKID is fetched by default, such that it is unnecessary to explicitly
// specify it.
List queryColumns = new ArrayList();
queryColumns.add("TASKNUMBER");    
queryColumns.add("TITLE");
queryColumns.add("PRIORITY");
queryColumns.add("STATE");
queryColumns.add("ENDDATE");
queryColumns.add("NUMBERATTRIBUTE1");
queryColumns.add("TEXTATTRIBUTE1");

43.4.5.5 Construct a List of OptionalInfo Items to be Returned from queryTasks()

This step is optional.

Per the API documentation, the OptionalInfo enumeration consists of additional, optional values that can be obtained with the task in the result set. These optional values include the available actions for a task, attachments, user comments, and so on. An example is shown in Example 43-20.

Example 43-20 Constructing a List of OptionalInfo Items

// List of optional info
// You can fetch any specified optionalInfo items from the Task object.
// For example: if you have specified "CustomActions", you can retrieve
// it using task.getSystemAttributes().getCustomActions();
// "Actions" (All Actions) - task.getSystemAttributes().getSystemActions()
// "GroupActions" (Only group Actions: Actions that can be permoded by the user
// as a member of a group).
//                - task.getSystemAttributes().getSystemActions()
// "ShortHistory" - task.getSystemAttributes().getShortHistory()
List optionalInfo = new ArrayList();
optionalInfo.add("Actions");

43.4.5.6 Invoke queryTasks() with the Attribute Lists

Now that the attribute classes have been constructed to constrain, order and specify the attributes returned in the query, invoke the queryTasks() method.

The query service API has the method signature shown in Example 43-21.

Example 43-21 Query Service API

queryTasks(IWorkflowContext ctx, java.util.List displayColumns, 
           java.util.List<ITaskQueryService.OptionalInfo> optionalInformation,
           ITaskQueryService.AssignmentFilter assignmentFilter,
           java.lang.String keywords,
           Predicate predicate,
           Ordering ordering,
           int startRow,
           int endRow)

The queryTasks() method returns a list of tasks that match the predicate and ordering criterion.

Example 43-22 shows how to invoke queryTasks() using the previously constructed attribute lists.

Example 43-22 Invoking queryTasks() with the Previously Constructed Attribute Lists

List tasksList = querySvc.queryTasks(wfCtxt,
                                     queryColumns,
                                     optionalInfo, 
                                     ITaskQueryService.ASSIGNMENT_FILTER_MY_AND_GROUP,
                                     keyword,
                                     predicate,
                                     ordering,
                                     0,0); // No Paging
 

More information on paging is available in the API documentation. (Look for the text "How to use paging.")

43.4.5.7 Iterate through the Result Set

The method queryTasks returns a list of task objects. Use standard Java iteration to iterate through the list. Then, invoke various accessors to obtain the attributes specified in the query column list. Example 43-23 shows how to iterate through the result set.

Example 43-23 Iterating through the Result Set

if (tasksList != null) { // There are tasks  
 str = str + tasksList.size() + ":";  
Task task = null;  
for (int i = 0; i < tasksList.size(); i++) {
     task = (Task) tasksList.get(i);
     str = str + task.getSystemAttributes().getTaskNumber() + "/" + task.getSystemAttributes().getTaskId();
     System.out.println("Task Number: " + task.getSystemAttributes().getTaskNumber());    
     System.out.println("Task Id: " + task.getSystemAttributes().getTaskId());    
     System.out.println("Title: " + task.getTitle());    
     System.out.println("Priority: " + task.getPriority());    
     System.out.println("State: " + task.getSystemAttributes().getState());    
     System.out.println();    
     // Retrive any Optional Info specified    
     // Use task service, to perform operations on the task    
     str = str + ":";   }
}

43.4.5.8 Programmatically Set the Task Outcome

Once you have obtained one or more task objects through the query service, approve or reject the tasks by calling the task service updateTaskOutcome method from the ITaskService API, as shown in the following examples:

Example 43-24 Programmatically Setting the Task Outcome

updateTaskOutcome(IWorkflowContext context,Task task, java.lang.String outcome)
// Set the outcome of the task. 

Example 43-25 Setting the Outcome of the Task Reference on the Single Server Task Service

'APPROVE'.taskSvc.updateTaskOutcome(wfCtxt, t, "APPROVE");

Example 43-26 Setting the Outcome of the Task Reference on the Single Server Task Service

'REJECT'.taskSvc.updateTaskOutcome(wfCtxt, t, "REJECT");

Example 43-27 Obtaining a Single Task Reference Using the Non-Federated Query Service

getTaskDetailsById, then setting the outcome to 'APPROVE'.Task t = querySvc.getTaskDetailsById(wfCtxt, "0a6d287a-9849-4e5e-914b-805706d6b9d9");
taskSvc.updateTaskOutcome(wfCtxt, t, "APPROVE");

Example 43-28 Obtaining a Single Task Reference Using the Non-Federated Query Service

getTaskDetailsByNumber, then setting the outcome to 'REJECT'.Task t = querySvc.getTaskDetailsByNumber(wfCtxt, 200140 );
taskSvc.updateTaskOutcome(wfCtxt, t, "REJECT");

Example 43-29 Updating a Single Task Outcome on the Federated Query Service

Map<String, IWorklowContext> ctxMap = fedWFCtx.getWorkflowContextMap()
String serverName = task.getServerName();
IWorklowContext taskWfCtx = ctxMap.get(serverName);
 
if (taskWfCtx !=null)

43.5 Other Approaches

Programmatically, it is possible to use a SOAP-based client interface and manually set endpoint and credential information in the code from a product-specific table. This approach is not recommended as the SOAP interface may negatively affect performance liability. Furthermore, managing endpoint or credential information yourself is not recommended. Endpoint implementation and credential provisioning are best facilitated by centralized endpoint management and identity propagation.

43.6 Securing the Design Pattern

Secure your human workflow client service in the manner appropriate for the type of code you are developing. For more information about securing your application, see Chapter 50, "Securing Web Services Use Cases."

43.7 Verifying the Deployment

Validating your implementation involves deploying human tasks to a SOA domain, in the following steps.

43.7.1 Deploying the Human Task

Upon deployment of the SOA composite containing the human task metadata, the human workflow infrastructure registers the task by name and namespace. Once the task is deployed and registered, your code or BPEL can initiate the task and facilitate task resolution through the code or worklist. For more information, see "Part V: Using the Human Workflow Service Component" in the Oracle Fusion Middleware Developer's Guide for Oracle SOA Suite.

43.7.2 Deploying Programmatic Task Functionality

Deploy the application containing the task service client code. Make sure to deploy the SOA composite with a task before deploying the human workflow task client service. This ensures that the SOA composite has been deployed before creating a task instance. For more information, see "Deploying SOA Composite Applications" in the Oracle Fusion Middleware Administrator's Guide for Oracle SOA Suite and Oracle Business Process Management Suite.

43.7.3 Invoking Programmatic Task Functionality

You can use Oracle ADF UI, an ADF Business Components service or an Oracle Enterprise Scheduler Java job to implement the task client service functionality. Submit or invoke the task functionality as you normally would, and use the Worklist application to confirm that tasks have been created and updated. You can access the Worklist application at the following URL.

http://host:port/integration/worklistapp

43.8 Troubleshooting the Use Case

Following are some suggestions for troubleshooting task data and the Java code in the use case.

43.8.1 Troubleshooting Task Data

In some cases, tasks may have been initiated but the attributes required for the task have not been set. When this happens, the task may not display in the worklist. Alternatively, it may be assigned to the wrong user, or to no user at all.

Check the WFTASK table for tasks such as these.

43.8.2 Troubleshooting Java Code

Use Oracle Fusion Middleware Extensions for Applications AppsLogger APIs to write execution and exception details to the diagnostic logs. You can also use the Oracle JDeveloper remote debugger to remotely connect to the runtime JVM and step through your code.

43.9 What You May Need to Know About Implementing Email Notification for an Oracle ADF Task Flow for a Human Task