Coverage Report - org.mule.transport.bpm.ProcessMessageDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
ProcessMessageDispatcher
0%
0/79
0%
0/60
0
 
 1  
 /*
 2  
  * $Id: ProcessMessageDispatcher.java 19710 2010-09-23 16:29:07Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.bpm;
 12  
 
 13  
 import org.mule.DefaultMuleMessage;
 14  
 import org.mule.api.MuleEvent;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.config.MuleProperties;
 17  
 import org.mule.api.endpoint.OutboundEndpoint;
 18  
 import org.mule.api.transport.DispatchException;
 19  
 import org.mule.api.transport.PropertyScope;
 20  
 import org.mule.config.i18n.MessageFactory;
 21  
 import org.mule.module.bpm.Process;
 22  
 import org.mule.transport.AbstractMessageDispatcher;
 23  
 import org.mule.transport.NullPayload;
 24  
 import org.mule.util.StringUtils;
 25  
 
 26  
 import java.util.HashMap;
 27  
 import java.util.Map;
 28  
 
 29  
 /**
 30  
  * Initiates or advances a workflow process from an outgoing Mule event.
 31  
  * 
 32  
  * @deprecated It is recommended to configure BPM as a component rather than a transport for 3.x
 33  
  */
 34  
 public class ProcessMessageDispatcher extends AbstractMessageDispatcher
 35  
 {
 36  
     private ProcessConnector connector;
 37  
 
 38  
     public ProcessMessageDispatcher(OutboundEndpoint endpoint)
 39  
     {
 40  0
         super(endpoint);
 41  0
         this.connector = (ProcessConnector)endpoint.getConnector();
 42  0
     }
 43  
 
 44  
     /**
 45  
      * Performs a synchronous action on the BPMS.
 46  
      * 
 47  
      * @return an object representing the new state of the process
 48  
      */
 49  
     @Override
 50  
     public MuleMessage doSend(MuleEvent event) throws Exception
 51  
     {
 52  0
         Object process = processAction(event);
 53  
 
 54  0
         if (process != null)
 55  
         {
 56  0
             MuleMessage msg = new DefaultMuleMessage(process, connector.getMuleContext());
 57  0
             msg.setProperty(Process.PROPERTY_PROCESS_ID, connector.getBpms().getId(process), PropertyScope.SESSION);
 58  0
             return msg;
 59  
         }
 60  
         else
 61  
         {
 62  0
             throw new DispatchException(
 63  
                 MessageFactory.createStaticMessage("Synchronous process invocation must return the new process state."),
 64  
                 event, this);
 65  
         }
 66  
     }
 67  
 
 68  
     /**
 69  
      * Performs an asynchronous action on the BPMS.
 70  
      */
 71  
     @Override
 72  
     public void doDispatch(MuleEvent event) throws Exception
 73  
     {
 74  0
         processAction(event);
 75  0
     }
 76  
 
 77  
     protected Object processAction(MuleEvent event) throws Exception
 78  
     {
 79  
         // An object representing the new state of the process
 80  
         Object process;
 81  
 
 82  
         // Create a map of process variables based on the message properties.
 83  0
         Map processVariables = new HashMap();
 84  0
         if (event != null)
 85  
         {
 86  0
             populateProcessVariables(event, processVariables, PropertyScope.INVOCATION);
 87  0
             populateProcessVariables(event, processVariables, PropertyScope.OUTBOUND);
 88  
 
 89  0
             Object payload = event.getMessage().getPayload();
 90  0
             if (payload != null && !(payload instanceof NullPayload))
 91  
             {
 92  
                 // Store the message's payload as a process variable.
 93  0
                 processVariables.put(Process.PROCESS_VARIABLE_INCOMING, payload);
 94  
 
 95  
                 // Store the endpoint on which the message was received as a process variable.
 96  0
                 String originatingEndpoint = event.getMessage().getInboundProperty(MuleProperties.MULE_ORIGINATING_ENDPOINT_PROPERTY);
 97  0
                 if (StringUtils.isNotEmpty(originatingEndpoint))
 98  
                 {
 99  0
                     processVariables.put(Process.PROCESS_VARIABLE_INCOMING_SOURCE, originatingEndpoint);
 100  
                 }
 101  
             }
 102  
         }
 103  
 
 104  
         // Retrieve the parameters
 105  0
         Object processType = event.getMessage().getSessionProperty(Process.PROPERTY_PROCESS_TYPE);
 106  0
         if (processType == null)
 107  
         {
 108  0
             processType = event.getMessage().getInvocationProperty(Process.PROPERTY_PROCESS_TYPE);
 109  
         }
 110  0
         if (processType == null)
 111  
         {
 112  0
             processType = event.getMessage().getInboundProperty(Process.PROPERTY_PROCESS_TYPE);
 113  
         }
 114  0
         processVariables.remove(Process.PROPERTY_PROCESS_TYPE);
 115  
 
 116  0
         String processIdField = connector.getProcessIdField();
 117  0
         if (StringUtils.isEmpty(processIdField))
 118  
         {
 119  0
             processIdField = Process.PROPERTY_PROCESS_ID;
 120  
         }
 121  
 
 122  
         Object processId;
 123  0
         processId = event.getMessage().getSessionProperty(processIdField);
 124  0
         if (processId == null)
 125  
         {
 126  0
             processId = event.getMessage().getInvocationProperty(processIdField); 
 127  
         }
 128  0
         if (processId == null)
 129  
         {
 130  0
             processId = event.getMessage().getInboundProperty(processIdField); 
 131  
         }
 132  0
         processVariables.remove(processIdField);
 133  
 
 134  
         // Default action is "advance"
 135  0
         String action = event.getMessage().getInvocationProperty(Process.PROPERTY_ACTION, Process.ACTION_ADVANCE);
 136  0
         processVariables.remove(Process.PROPERTY_ACTION);
 137  
 
 138  0
         Object transition = event.getMessage().getInvocationProperty(Process.PROPERTY_TRANSITION);
 139  0
         processVariables.remove(Process.PROPERTY_TRANSITION);
 140  
 
 141  
         // Decode the URI, for example:
 142  
         // bpm://testProcess/4561?action=advance
 143  
         String temp;
 144  0
         temp = event.getEndpoint().getEndpointURI().getHost();
 145  0
         if (StringUtils.isNotEmpty(temp))
 146  
         {
 147  0
             processType = temp;
 148  
         }
 149  0
         temp = event.getEndpoint().getEndpointURI().getPath();
 150  0
         if (StringUtils.isNotEmpty(temp))
 151  
         {
 152  
             // Strip the leading "/" from the path.
 153  0
             if (temp.startsWith("/"))
 154  
             {
 155  0
                 temp = StringUtils.right(temp, temp.length() - 1);
 156  
             }
 157  
             // If there are any remaining "/", we don't know what to do with them.
 158  0
             if (temp.indexOf("/") != -1)
 159  
             {
 160  0
                 throw new IllegalArgumentException("Unexpected format in the path of the URL: " + temp);
 161  
             }
 162  0
             processId = temp;
 163  
         }
 164  
 
 165  
         // //////////////////////////////////////////////////////////////////////
 166  
 
 167  0
         logger.debug("Message received: payload = " + event.getMessage().getPayload().getClass().getName() + " processType = " + processType + " processId = " + processId + " action = " + action);
 168  
         
 169  
         // Start a new process.
 170  0
         if (processId == null || action.equals(Process.ACTION_START))
 171  
         {
 172  0
             if (processType != null)
 173  
             {
 174  0
                 process = connector.getBpms().startProcess(processType, transition, processVariables);
 175  0
                 if ((process != null) && logger.isInfoEnabled())
 176  
                 {
 177  0
                     logger.info("New process started, ID = " + connector.getBpms().getId(process));
 178  
                 }
 179  
             }
 180  
             else
 181  
             {
 182  0
                 throw new IllegalArgumentException("Process type is missing, cannot start a new process.");
 183  
             }
 184  
         }
 185  
 
 186  
         // Don't advance the process, just update the process variables.
 187  0
         else if (action.equals(Process.ACTION_UPDATE))
 188  
         {
 189  0
             if (processId != null)
 190  
             {
 191  0
                 process = connector.getBpms().updateProcess(processId, processVariables);
 192  0
                 if ((process != null) && logger.isInfoEnabled())
 193  
                 {
 194  0
                     logger.info("Process variables updated, ID = " + connector.getBpms().getId(process));
 195  
                 }
 196  
             }
 197  
             else
 198  
             {
 199  0
                 throw new IllegalArgumentException("Process ID is missing, cannot update process.");
 200  
             }
 201  
         }
 202  
 
 203  
         // Abort the running process (end abnormally).
 204  0
         else if (action.equals(Process.ACTION_ABORT))
 205  
         {
 206  0
             if (processId != null)
 207  
             {
 208  0
                 connector.getBpms().abortProcess(processId);
 209  0
                 process = NullPayload.getInstance();
 210  0
                 logger.info("Process aborted, ID = " + processId);
 211  
             }
 212  
             else
 213  
             {
 214  0
                 throw new IllegalArgumentException("Process ID is missing, cannot abort process.");
 215  
             }
 216  
         }
 217  
 
 218  
         // Advance the already-running process one step.
 219  
         else
 220  
         {
 221  0
             if (processId != null)
 222  
             {
 223  0
                 process = connector.getBpms().advanceProcess(processId, transition, processVariables);
 224  0
                 if ((process != null) && logger.isInfoEnabled())
 225  
                 {
 226  0
                     logger.info("Process advanced, ID = " + connector.getBpms().getId(process)
 227  
                                     + ", new state = " + connector.getBpms().getState(process));
 228  
                 }
 229  
             }
 230  
             else
 231  
             {
 232  0
                 throw new IllegalArgumentException("Process ID is missing, cannot advance process.");
 233  
             }
 234  
         }
 235  
 
 236  0
         return process;
 237  
     }
 238  
 
 239  
     protected void populateProcessVariables(MuleEvent event, Map processVariables, PropertyScope propertyScope)
 240  
     {
 241  0
         for (String propertyName : event.getMessage().getPropertyNames(propertyScope))
 242  
         {
 243  
             // The session property can become rather large and causes problems with DB persistence.
 244  0
             if (!propertyName.equals(MuleProperties.MULE_SESSION_PROPERTY))
 245  
             {
 246  0
                 processVariables.put(propertyName, event.getMessage().getProperty(propertyName, propertyScope));
 247  
             }
 248  
         }
 249  0
     }
 250  
 }