Tuesday, May 29, 2012

Update the Human task payload via JAVA API - Oracle SOA Suite

Update the Human task payload via JAVA API - Oracle SOA Suite:

Oracle SOA Suite provides java API’s to manipulate the Human task data.The below java code will help us to update the Human task payload.

This is the Remote Java client  to get the Workflow service and perform the required operations on the task.

The XPath of the input element will be used to update the payload data.

UpdateWorkflowPayload.java

import java.util.*;
import oracle.bpel.services.workflow.IWorkflowConstants;
import oracle.bpel.services.workflow.client.*;
import oracle.bpel.services.workflow.query.ITaskQueryService;
import oracle.bpel.services.workflow.repos.*;
import oracle.bpel.services.workflow.task.ITaskService;
import oracle.bpel.services.workflow.task.model.Task;
import oracle.bpel.services.workflow.verification.IWorkflowContext;
import org.w3c.dom.Element;
public class UpdateWorkflowPayload {     
   public static void updatePayload()
    {
        List displayColumns = new ArrayList();
        displayColumns.add("TASKNUMBER");
        displayColumns.add("TITLE");
        displayColumns.add("STATE");
        displayColumns.add("CREATOR");
        List optionalInfo = new ArrayList();      
        optionalInfo.add("Comments");
        optionalInfo.add("Payload");      
    try {
              String userid="weblogic";
              String password = "password";       
              String serverUrl ="t3://localhost:8000"; // host:port of the soa server
              Map<IWorkflowServiceClientConstants.CONNECTION_PROPERTY, String> connProperties = new HashMap<IWorkflowServiceClientConstants.CONNECTION_PROPERTY, String>();              connProperties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.CLIENT_TYPE,WorkflowServiceClientFactory.REMOTE_CLIENT);              connProperties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL,serverUrl);
              connProperties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");       
              IWorkflowServiceClient wfSvcClient = WorkflowServiceClientFactory.getWorkflowServiceClient(connProperties, null, null);   
              IWorkflowContext ctx = wfSvcClient.getTaskQueryService().authenticate(userid, password.toCharArray(), "jazn.com" );
              ITaskQueryService querySvc = wfSvcClient.getTaskQueryService();
              ITaskService taskSvc = wfSvcClient.getTaskService();       
              Predicate statePredicate =new Predicate(TableConstants.WFTASK_STATE_COLUMN,Predicate.OP_EQ,IWorkflowConstants.TASK_STATE_ASSIGNED);
              Predicate compositenamePredicate = new Predicate(TableConstants.COMPONENT_COMPOSITE_NAME_COLUMN,Predicate.OP_EQ,"HumanWorkflow");
              Predicate predicate = new Predicate(statePredicate, Predicate.AND, compositenamePredicate);
            
       
              List tasks =querySvc.queryTasks(ctx, displayColumns, optionalInfo, ITaskQueryService.AssignmentFilter.MY,null, statePredicate, null, 0, 0);
              
              for (int i = 0; i < tasks.size(); i++) {
                       Task task = (Task)tasks.get(i);
                       String taskId = task.getSystemAttributes().getTaskId();                
                       String title = task.getTitle();
                       String state = task.getSystemAttributes().getState();
                       Task currentTask=querySvc.getTaskDetailsById(ctx,taskId);                   
                 
                       Element payload = currentTask.getPayloadAsElement();
                 
                       Map namespacemap = new HashMap();
                       namespacemap.put("ns0", "http://xmlns.oracle.com/bpel/workflow/task");
                                     
                       setPayloadValue(payload,"/ns0:task/ns0:payload/ns0:Name",namespacemap,"Albin Issac");
                       setPayloadValue(payload,"/ns0:task/ns0:payload/ns0:Number",namespacemap,"024");
                       setPayloadValue(payload,"/ns0:task/ns0:payload/ns0:Dep",namespacemap,"I.T");
                       setPayloadValue(payload,"/ns0:task/ns0:payload/ns0:Place",namespacemap,"KAMPLAR");
                 
                       currentTask.setPayloadAsElement(payload);    
                       taskSvc.updateTaskOutcome(ctx, currentTask,"APPROVE"); 
                 
                   }
                         
          } catch (Exception e) {
              e.printStackTrace();
          
          }
    }
  
   public static void setPayloadValue(Element payload,String xpath,Map namespacemap,String value) {
        try {
            XPathUtils.setNodeValue(payload, namespacemap, xpath,value);
        } catch (Exception e) {
        }
    }
   public static void main(String[] args) {
        updatePayload();
    }
}


XPathUtils.java

(To perform the XPath related operations)
import java.util.Map;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.*;
import oracle.bpel.services.common.util.XMLUtil;
import oracle.fabric.common.xml.xpath.SimpleNamespaceContext;
import org.w3c.dom.*;
public class XPathUtils {
    public static void setNodeValue(Element payload, Map namespacemap, String xpath,
                         String value) throws Exception {
           Node node = null;
           NodeList nodes = null;
           NodeList children =null;
           int length = 0;
           try {
               nodes = XPathUtils.selectNodes(XMLUtil.getDocumentElement(payload), xpath, namespacemap);
           } catch (Exception e) {
               e.printStackTrace();
               throw e;
           }
           node = nodes.item(0);          
           if(nodes.getLength()>0){
           children = node.getChildNodes();
           length = children.getLength();          
           if (length == 1) {
               Node textNode = children.item(0);
               String oldValue = textNode.getNodeValue();               
               value=value==null?"":value;
               oldValue=oldValue==null?"":oldValue;              
               if (!oldValue.equals(value)) {
                   textNode.setNodeValue(value);
               }
           } else if (length == 0 && value != null && !value.equals("")) {
               Node valueNode = node.getOwnerDocument().createTextNode(value);
               node.appendChild(valueNode);
               }
           }
       }
   
    public static NodeList selectNodes(Element pElement, String xpathExpression, Map prefixNamespaceMapping)  throws Exception {
           XPath xPath = createXPath(prefixNamespaceMapping);
           Document doc = null;
           if(pElement instanceof Document)
               doc = (Document)pElement;
           else
               doc = pElement != null ? pElement.getOwnerDocument() : null;
           NodeList value = (NodeList)xPath.evaluate(xpathExpression, doc, XPathConstants.NODESET);
           return value;
       }
    public static  String getNodeValue(NodeList nodes) {
         Node node = nodes.item(0);
         String value = null;
         if(nodes.getLength()>0){
         NodeList children = node.getChildNodes();
         int length = children.getLength();
         if (length == 1) {
             Node textNode = children.item(0);
             value = textNode.getNodeValue();
         }
         }
         return value;
        
     }     
    private static XPath createXPath(Map namespaceMapping)
      {
          XPath xpath = null;
          NamespaceContext nc = null;
          if(namespaceMapping != null)
          {
              if(namespaceMapping.containsKey(""))
                  namespaceMapping.remove("");
              nc = new SimpleNamespaceContext(namespaceMapping);
          }
          xpath = getXPath(nc);
          return xpath;
      }
   
    public static XPath getXPath(NamespaceContext nsContext)
        {
            XPath xpath = XPathFactory.newInstance().newXPath();
            if(nsContext != null)
                xpath.setNamespaceContext(nsContext);
            return xpath;
        }   
}

Jar Files Required:




O/P

Input Payload:




Updated payload:



11 comments:

  1. Good to see your post a bit lately. I came across the similar requirement recently.

    This is how I implemented the logic as follows.

    public void updateTaskPayload(Task task, Map newRequestPayloadMap) throws WorkflowException, StaleObjectException{
    task = getTaskQueryService().getTaskDetailsByNumber(null, task.getSystemAttributes().getTaskNumber());
    XMLElement taskPayloadElement = (XMLElement)task.getPayloadAsElement();
    for(Map.Entry entry : newRequestPayloadMap.entrySet()){
    setPayloadValue(taskPayloadElement, entry.getKey(), entry.getValue());
    }
    task.setPayloadAsElement(taskPayloadElement);
    getTaskUpdateService().updateTask(null, task);
    getTaskUpdateService().releaseTask(null, task); // Need to release the task
    }
    public void setPayloadValue(XMLElement taskPayloadElement, String pNodeName, String pNodeValue){
    NodeList myNodeList = taskPayloadElement.getElementsByTagName(pNodeName);
    if(myNodeList!=null && myNodeList.getLength() > 0){
    Element myElement = (Element)myNodeList.item(0);
    myElement.getFirstChild().setNodeValue(pNodeValue);
    }
    }

    ReplyDelete
  2. Hi

    It was very helpful , I need this in my project, But i am getting null in workflowContext object.:( , I follow all instructions as above, But i am not sure why it's giving null.

    Thanks,
    Krrish

    ReplyDelete
    Replies
    1. I hope you are using the SOA server details.

      If it fails after using the SOA server details then the issue might be with the JAR files.

      Try to use all the jars mentioned from the server location directly(don't copy the jars to a folder and refer it).

      Regards
      Albin I

      Delete
  3. Hi Upon executing the code I am getting the below error:
    <<.> VerficationService.checkOrLogUserTaskAction: Checking if user weblogic
    can perform action RELEASE failed. Task Details: Task Id: 9ff3e0cf-c842-412f-97a6-a3351b383c71 State: ASSIGNED AssigeeUsers: [] AcquiredBy: null Permitted actions are: [UP
    DATE_COMMENT, SKIP_CURRENT_ASSIGNMENT, VIEW_SUB_TASKS, DELEGATE, SUSPEND, UPDATE, UPDATE_ATTACHMENT, SUSPEND_TIMERS, ESCALATE, VIEW_PROCESS_HISTORY, REASSIGN, VIEW_TASK, C
    USTOM, OVERRIDE_ROUTING_SLIP, WITHDRAW, ACQUIRE, VIEW_TASK_HISTORY, REDECISION] Roles played by user:[PUBLIC, ASSIGNEES, ADMIN, default.DefaultPerformer] Task Organization
    alUnitId: null User OrganizationalUnits:[]>
    <<.> Invalid action on workflow task or user does not have privilege to perform this
    action.
    Action RELEASE on task 9ff3e0cf-c842-412f-97a6-a3351b383c71 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.

    ORABPEL-30036

    Invalid action on workflow task or user does not have privilege to perform this action.
    Action RELEASE on task 9ff3e0cf-c842-412f-97a6-a3351b383c71 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.


    Pls help also the code is not updating the task if executed from ADF screens binded to the task.But if invoked externally it works fine but locks the instance by weblogic and is not releasing the task.I checked privileges of weblogic ,he has all the access.

    ReplyDelete
    Replies
    1. I figured it out...evrytime you have to use a different context for these two operations.both update and release does not work in same context connection.hope it helps other as i spent half a day on this problem.

      Regards,
      Ritu

      Delete
  4. it’s very use full to get idea about human task flow through java API


    I have requirement like to add the extra tags to the task payload for ex:

    Current task like




    ABC









    3456

    10000









    I need to add more invoice lines to the payload without affecting the existing invoice liens,

    Could you please suggest the some approach.


    Thanks,

    Madhava.

    ReplyDelete
  5. Design your XSD such a way that it will accept multiple invoice lines.
    Use the Java API with DOM parser to add the extra invoice lines to the task payload.

    Regards
    Albin I

    ReplyDelete
  6. Hi Albin,

    Appreciate the write up. The xml payload setting with namespace stuff did not work for me though. I might have made a mistake. But another way to set payload without digging into namespace would be to use DOM Parser and set the values.
    http://www.mkyong.com/java/how-to-modify-xml-file-in-java-dom-parser/
    Hope this helps someone like me.

    Thanks

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Hi Albin,

    I am testing my update task by soap client what minimum payload can i use? I am passing credential and taskId but getting error.

    Please help me to get required parameters to update task.

    Thanks

    ReplyDelete