Coverage Report - org.mule.transport.bpm.ProcessConnector
 
Classes in this File Line Coverage Branch Coverage Complexity
ProcessConnector
50%
28/56
20%
4/20
1.842
 
 1  
 /*
 2  
  * $Id: ProcessConnector.java 11541 2008-04-08 18:09:49Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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.api.MuleException;
 14  
 import org.mule.api.MuleMessage;
 15  
 import org.mule.api.config.ConfigurationException;
 16  
 import org.mule.api.config.MuleProperties;
 17  
 import org.mule.api.lifecycle.InitialisationException;
 18  
 import org.mule.config.i18n.MessageFactory;
 19  
 import org.mule.module.client.MuleClient;
 20  
 import org.mule.transport.AbstractConnector;
 21  
 import org.mule.util.StringUtils;
 22  
 
 23  
 import java.util.Map;
 24  
 
 25  
 /**
 26  
  * The BPM provider allows Mule events to initiate and/or advance processes in an
 27  
  * external or embedded Business Process Management System (BPMS). It also allows
 28  
  * executing processes to generate Mule events.
 29  
  */
 30  30
 public class ProcessConnector extends AbstractConnector implements MessageService
 31  
 {
 32  
 
 33  
     /** The underlying BPMS */
 34  
     protected BPMS bpms;
 35  
 
 36  
     /** This field will be used to correlate messages with processes. */
 37  
     protected String processIdField;
 38  
 
 39  
     /**
 40  
      * The global receiver allows an endpoint of type "bpm://*" to receive any
 41  
      * incoming message to the BPMS, regardless of the process. If this is false, the
 42  
      * process name must be specified for each endpoint, e.g. "bpm://MyProcess" will
 43  
      * only receive messages for the process "MyProcess".
 44  
      */
 45  30
     protected boolean allowGlobalReceiver = false;
 46  
 
 47  
     /**
 48  
      * If false, any message generated by the process is routed from the service on 
 49  
      * which it is received.  If true, a process can send messages to any endpoint
 50  
      * on any service.
 51  
      */
 52  30
     protected boolean allowGlobalDispatcher = false;
 53  
 
 54  
     public static final String BPM_PROPERTY_PREFIX = "BPM_";
 55  
     
 56  
     public static final String PROPERTY_ENDPOINT = 
 57  
         MuleProperties.PROPERTY_PREFIX + BPM_PROPERTY_PREFIX + "ENDPOINT";
 58  
     public static final String PROPERTY_PROCESS_TYPE = 
 59  
         MuleProperties.PROPERTY_PREFIX + BPM_PROPERTY_PREFIX + "PROCESS_TYPE";
 60  
     public static final String PROPERTY_PROCESS_ID = 
 61  
         MuleProperties.PROPERTY_PREFIX + BPM_PROPERTY_PREFIX + "PROCESS_ID";
 62  
     public static final String PROPERTY_ACTION = 
 63  
         MuleProperties.PROPERTY_PREFIX + BPM_PROPERTY_PREFIX + "ACTION";
 64  
     public static final String PROPERTY_TRANSITION = 
 65  
         MuleProperties.PROPERTY_PREFIX + BPM_PROPERTY_PREFIX + "TRANSITION";
 66  
     public static final String PROPERTY_PROCESS_STARTED = 
 67  
         MuleProperties.PROPERTY_PREFIX + BPM_PROPERTY_PREFIX + "STARTED";
 68  
     
 69  
     public static final String ACTION_START = "start";
 70  
     public static final String ACTION_ADVANCE = "advance";
 71  
     public static final String ACTION_UPDATE = "update";
 72  
     public static final String ACTION_ABORT = "abort";
 73  
     
 74  
     public static final String PROCESS_VARIABLE_INCOMING = "incoming";
 75  
     public static final String PROCESS_VARIABLE_INCOMING_SOURCE = "incomingSource";
 76  
     public static final String PROCESS_VARIABLE_DATA = "data";
 77  
 
 78  
     public static final String PROTOCOL = "bpm";
 79  
     public static final String GLOBAL_RECEIVER = PROTOCOL + "://*";
 80  
 
 81  30
     private MuleClient muleClient = null;
 82  
 
 83  
     public String getProtocol()
 84  
     {
 85  64
         return PROTOCOL;
 86  
     }
 87  
 
 88  
     protected void doInitialise() throws InitialisationException
 89  
     {
 90  
         try
 91  
         {
 92  30
             if (bpms == null)
 93  
             {
 94  0
                 throw new ConfigurationException(
 95  
                     MessageFactory.createStaticMessage("The bpms property must be set for this connector."));
 96  
             }
 97  
 
 98  
             // Set a callback so that the BPMS may generate messages within Mule.
 99  30
             bpms.setMessageService(this);
 100  
             
 101  
             // The MuleClient is used as a global dispatcher.  
 102  
             // TODO MULE-1221 It would be cleaner to use something like the dynamic:// transport
 103  30
             if ((allowGlobalDispatcher == true) && (muleClient == null))
 104  
             {
 105  4
                 muleClient = new MuleClient(muleContext);
 106  
             }
 107  
         }
 108  0
         catch (Exception e)
 109  
         {
 110  0
             throw new InitialisationException(e, this);
 111  30
         }
 112  30
     }
 113  
 
 114  
     protected void doDispose()
 115  
     {
 116  
         // template method
 117  46
     }
 118  
 
 119  
     protected void doConnect() throws Exception
 120  
     {
 121  
         // template method
 122  28
     }
 123  
 
 124  
     protected void doDisconnect() throws Exception
 125  
     {
 126  
         // template method
 127  28
     }
 128  
 
 129  
     protected void doStart() throws MuleException
 130  
     {
 131  
         // template method
 132  28
     }
 133  
 
 134  
     protected void doStop() throws MuleException
 135  
     {
 136  
         // template method
 137  28
     }
 138  
 
 139  
     /**
 140  
      * This method looks for a receiver based on the process name and ID. It searches
 141  
      * iteratively from the narrowest scope (match process name and ID) to the widest
 142  
      * scope (match neither - global receiver) possible.
 143  
      * 
 144  
      * @return ProcessMessageReceiver or null if no match is found
 145  
      */
 146  
     public ProcessMessageReceiver lookupReceiver(String processName, Object processId)
 147  
     {
 148  0
         ProcessMessageReceiver receiver = (ProcessMessageReceiver)lookupReceiver(toUrl(processName, processId));
 149  0
         if (receiver == null)
 150  
         {
 151  0
             receiver = (ProcessMessageReceiver)lookupReceiver(toUrl(processName, null));
 152  
         }
 153  0
         if (receiver == null)
 154  
         {
 155  0
             receiver = (ProcessMessageReceiver)lookupReceiver(toUrl(null, null));
 156  
         }
 157  0
         return receiver;
 158  
     }
 159  
 
 160  
     /**
 161  
      * Generate a URL based on the process name and ID such as "bpm://myProcess/2342"
 162  
      * If the parameters are missing, and <code>allowGlobalReceiver</code> is true,
 163  
      * the GLOBAL_RECEIVER is returned.
 164  
      */
 165  
     public String toUrl(String processName, Object processId)
 166  
     {
 167  0
         String url = getProtocol() + "://";
 168  0
         if (StringUtils.isNotEmpty(processName))
 169  
         {
 170  0
             url += processName;
 171  0
             if (processId != null)
 172  
             {
 173  0
                 url += "/" + processId;
 174  
             }
 175  
         }
 176  0
         else if (isAllowGlobalReceiver())
 177  
         {
 178  0
             return GLOBAL_RECEIVER;
 179  
         }
 180  
         else
 181  
         {
 182  0
             throw new IllegalArgumentException(
 183  
                 "No valid URL could be created for the given process name and ID: processName = " + processName + ", processId = " + processId);
 184  
         }
 185  0
         return url;
 186  
     }
 187  
 
 188  
     public MuleMessage generateMessage(String endpoint,
 189  
                                       Object payloadObject,
 190  
                                       Map messageProperties,
 191  
                                       boolean synchronous) throws Exception
 192  
     {
 193  0
         String processName = (String)messageProperties.get(ProcessConnector.PROPERTY_PROCESS_TYPE);
 194  0
         Object processId = messageProperties.get(ProcessConnector.PROPERTY_PROCESS_ID);
 195  
 
 196  
         // Look up a receiver for this process.
 197  0
         ProcessMessageReceiver receiver = lookupReceiver(processName, processId);
 198  0
         if (receiver == null)
 199  
         {
 200  0
             throw new ConfigurationException(MessageFactory
 201  
                 .createStaticMessage("No corresponding receiver found for processName = " + processName
 202  
                                 + ", processId = " + processId));
 203  
         }
 204  
 
 205  0
         if (synchronous)
 206  
         {
 207  
             // Send the process-generated Mule message synchronously.
 208  0
             return receiver.generateSynchronousEvent(endpoint, payloadObject, messageProperties);
 209  
         }
 210  
         else
 211  
         {
 212  
             // Dispatch the process-generated Mule message asynchronously.
 213  0
             receiver.generateAsynchronousEvent(endpoint, payloadObject, messageProperties);
 214  0
             return null;
 215  
         }
 216  
     }
 217  
 
 218  
     // //////////////////////////////////////////////////////////////////////////
 219  
     // Getters and Setters
 220  
     // //////////////////////////////////////////////////////////////////////////
 221  
 
 222  
     public BPMS getBpms()
 223  
     {
 224  4
         return bpms;
 225  
     }
 226  
 
 227  
     public void setBpms(BPMS bpms)
 228  
     {
 229  32
         this.bpms = bpms;
 230  32
     }
 231  
 
 232  
     public MuleClient getMuleClient()
 233  
     {
 234  0
         return muleClient;
 235  
     }
 236  
 
 237  
     public boolean isAllowGlobalDispatcher()
 238  
     {
 239  4
         return allowGlobalDispatcher;
 240  
     }
 241  
 
 242  
     public void setAllowGlobalDispatcher(boolean allowGlobalDispatcher)
 243  
     {
 244  8
         this.allowGlobalDispatcher = allowGlobalDispatcher;
 245  8
     }
 246  
 
 247  
     public boolean isAllowGlobalReceiver()
 248  
     {
 249  4
         return allowGlobalReceiver;
 250  
     }
 251  
 
 252  
     public void setAllowGlobalReceiver(boolean allowGlobalReceiver)
 253  
     {
 254  8
         this.allowGlobalReceiver = allowGlobalReceiver;
 255  8
     }
 256  
 
 257  
     public String getProcessIdField()
 258  
     {
 259  4
         return processIdField;
 260  
     }
 261  
 
 262  
     public void setProcessIdField(String processIdField)
 263  
     {
 264  4
         this.processIdField = processIdField;
 265  4
     }
 266  
 }