Coverage Report - org.mule.impl.model.DefaultMuleProxy
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultMuleProxy
48%
78/164
32%
30/94
3.35
 
 1  
 /*
 2  
  * $Id: DefaultMuleProxy.java 11728 2008-05-13 07:31:11Z dirk.olmes $
 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.impl.model;
 12  
 
 13  
 import org.mule.config.MuleProperties;
 14  
 import org.mule.config.i18n.CoreMessages;
 15  
 import org.mule.impl.ImmutableMuleDescriptor;
 16  
 import org.mule.impl.InterceptorsInvoker;
 17  
 import org.mule.impl.MuleDescriptor;
 18  
 import org.mule.impl.MuleEvent;
 19  
 import org.mule.impl.MuleMessage;
 20  
 import org.mule.impl.OptimizedRequestContext;
 21  
 import org.mule.impl.RequestContext;
 22  
 import org.mule.impl.endpoint.MuleEndpoint;
 23  
 import org.mule.impl.endpoint.MuleEndpointURI;
 24  
 import org.mule.impl.message.ExceptionPayload;
 25  
 import org.mule.management.stats.ComponentStatistics;
 26  
 import org.mule.providers.AbstractConnector;
 27  
 import org.mule.providers.NullPayload;
 28  
 import org.mule.providers.ReplyToHandler;
 29  
 import org.mule.umo.MessagingException;
 30  
 import org.mule.umo.UMOEvent;
 31  
 import org.mule.umo.UMOException;
 32  
 import org.mule.umo.UMOExceptionPayload;
 33  
 import org.mule.umo.UMOImmutableDescriptor;
 34  
 import org.mule.umo.UMOInterceptor;
 35  
 import org.mule.umo.UMOMessage;
 36  
 import org.mule.umo.endpoint.UMOEndpoint;
 37  
 import org.mule.umo.endpoint.UMOEndpointURI;
 38  
 import org.mule.umo.endpoint.UMOImmutableEndpoint;
 39  
 import org.mule.umo.lifecycle.Disposable;
 40  
 import org.mule.umo.lifecycle.Initialisable;
 41  
 import org.mule.umo.lifecycle.UMOLifecycleAdapter;
 42  
 import org.mule.umo.model.ModelException;
 43  
 import org.mule.umo.model.UMOEntryPointResolver;
 44  
 import org.mule.umo.model.UMOModel;
 45  
 import org.mule.util.queue.QueueSession;
 46  
 
 47  
 import java.util.ArrayList;
 48  
 import java.util.Iterator;
 49  
 import java.util.List;
 50  
 import java.util.Map;
 51  
 
 52  
 import org.apache.commons.logging.Log;
 53  
 import org.apache.commons.logging.LogFactory;
 54  
 
 55  
 /**
 56  
  * <code>MuleProxy</code> is a proxy to a UMO. It is a poolable object that that
 57  
  * can be executed in it's own thread.
 58  
  */
 59  
 
 60  
 public class DefaultMuleProxy implements MuleProxy
 61  
 {
 62  
     /**
 63  
      * logger used by this class
 64  
      */
 65  4
     private static Log logger = LogFactory.getLog(DefaultMuleProxy.class);
 66  
 
 67  
     /**
 68  
      * Holds the current event being processed
 69  
      */
 70  
     private UMOEvent event;
 71  
 
 72  
     /**
 73  
      * Holds the actual UMO
 74  
      */
 75  
     private UMOLifecycleAdapter umo;
 76  
 
 77  
     /**
 78  
      * holds the UMO descriptor
 79  
      */
 80  
     private ImmutableMuleDescriptor descriptor;
 81  
 
 82  
     /**
 83  
      * Determines if the proxy is suspended
 84  
      */
 85  80
     private boolean suspended = true;
 86  
 
 87  
     private List interceptorList;
 88  
 
 89  80
     private ComponentStatistics stat = null;
 90  
 
 91  80
     private QueueSession queueSession = null;
 92  
 
 93  
     /**
 94  
      * Constructs a Proxy using the UMO's AbstractMessageDispatcher and the UMO
 95  
      * itself
 96  
      * 
 97  
      * @param component the underlying object that with receive events
 98  
      * @param descriptor the UMOComponent descriptor associated with the component
 99  
      */
 100  
     public DefaultMuleProxy(Object component, MuleDescriptor descriptor, UMOModel model) throws UMOException
 101  80
     {
 102  80
         this.descriptor = new ImmutableMuleDescriptor(descriptor);
 103  
 
 104  80
         UMOEntryPointResolver resolver = model.getEntryPointResolver();
 105  80
         umo = model.getLifecycleAdapterFactory().create(component, descriptor, resolver);
 106  
 
 107  80
         interceptorList = new ArrayList(descriptor.getInterceptors().size() + 1);
 108  80
         interceptorList.addAll(descriptor.getInterceptors());
 109  80
         interceptorList.add(umo);
 110  
 
 111  80
         for (Iterator iter = interceptorList.iterator(); iter.hasNext();)
 112  
         {
 113  80
             UMOInterceptor interceptor = (UMOInterceptor) iter.next();
 114  80
             if (interceptor instanceof Initialisable)
 115  
             {
 116  
                 try
 117  
                 {
 118  80
                     ((Initialisable) interceptor).initialise();
 119  
                 }
 120  10
                 catch (Exception e)
 121  
                 {
 122  10
                     throw new ModelException(
 123  
                         CoreMessages.objectFailedToInitialise(
 124  
                             "Component '" + descriptor.getName() + "'"), e);
 125  70
                 }
 126  
             }
 127  70
         }
 128  70
     }
 129  
 
 130  
     public void start() throws UMOException
 131  
     {
 132  28
         checkDisposed();
 133  28
         if (!umo.isStarted())
 134  
         {
 135  
             try
 136  
             {
 137  28
                 umo.start();
 138  
             }
 139  0
             catch (Exception e)
 140  
             {
 141  0
                 throw new ModelException(
 142  
                     CoreMessages.failedToStart("Component '" + descriptor.getName() + "'"), e);
 143  28
             }
 144  
         }
 145  
 
 146  28
     }
 147  
 
 148  
     public boolean isStarted()
 149  
     {
 150  0
         return umo.isStarted();
 151  
     }
 152  
 
 153  
     public void stop() throws UMOException
 154  
     {
 155  24
         checkDisposed();
 156  24
         if (umo.isStarted())
 157  
         {
 158  
             try
 159  
             {
 160  24
                 umo.stop();
 161  
             }
 162  0
             catch (Exception e)
 163  
             {
 164  0
                 throw new ModelException(
 165  
                     CoreMessages.failedToStop("Component '" + descriptor.getName() + "'"), e);
 166  24
             }
 167  
         }
 168  24
     }
 169  
 
 170  
     public void dispose()
 171  
     {
 172  28
         checkDisposed();
 173  26
         for (Iterator iter = interceptorList.iterator(); iter.hasNext();)
 174  
         {
 175  26
             UMOInterceptor interceptor = (UMOInterceptor) iter.next();
 176  26
             if (interceptor instanceof Disposable)
 177  
             {
 178  
                 try
 179  
                 {
 180  26
                     ((Disposable) interceptor).dispose();
 181  
                 }
 182  0
                 catch (Exception e)
 183  
                 {
 184  
                     // We're being disposed. If there was an error while disposing the interceptor
 185  
                     // there's not much we can do here.
 186  0
                     logger.error(
 187  
                         CoreMessages.failedToDispose("Component '" + descriptor.getName() + "'"), e);
 188  26
                 }
 189  
             }
 190  26
         }
 191  26
     }
 192  
 
 193  
     private void checkDisposed()
 194  
     {
 195  80
         if (umo.isDisposed())
 196  
         {
 197  2
             throw new IllegalStateException("Component has already been disposed of");
 198  
         }
 199  78
     }
 200  
 
 201  
     /**
 202  
      * Sets the current event being processed
 203  
      * 
 204  
      * @param event the event being processed
 205  
      */
 206  
     public void onEvent(QueueSession session, UMOEvent event)
 207  
     {
 208  0
         this.queueSession = session;
 209  0
         this.event = event;
 210  0
     }
 211  
 
 212  
     public ComponentStatistics getStatistics()
 213  
     {
 214  0
         return stat;
 215  
     }
 216  
 
 217  
     public void setStatistics(ComponentStatistics stat)
 218  
     {
 219  18
         this.stat = stat;
 220  18
     }
 221  
 
 222  
     /**
 223  
      * Makes a synchronous call on the UMO
 224  
      * 
 225  
      * @param event the event to pass to the UMO
 226  
      * @return the return event from the UMO
 227  
      * @throws UMOException if the call fails
 228  
      */
 229  
     public Object onCall(UMOEvent event) throws UMOException
 230  
     {
 231  8
         if (logger.isTraceEnabled())
 232  
         {
 233  0
             logger.trace("MuleProxy: sync call for Mule UMO " + descriptor.getName());
 234  
         }
 235  
 
 236  8
         UMOMessage returnMessage = null;
 237  
         try
 238  
         {
 239  8
             if (event.getEndpoint().canReceive())
 240  
             {
 241  6
                 event = OptimizedRequestContext.unsafeSetEvent(event);
 242  6
                 Object replyTo = event.getMessage().getReplyTo();
 243  6
                 ReplyToHandler replyToHandler = getReplyToHandler(event.getMessage(), event.getEndpoint());
 244  6
                 InterceptorsInvoker invoker = new InterceptorsInvoker(interceptorList, descriptor,
 245  
                     event.getMessage());
 246  
 
 247  
                 // stats
 248  6
                 long startTime = 0;
 249  6
                 if (stat.isEnabled())
 250  
                 {
 251  0
                     startTime = System.currentTimeMillis();
 252  
                 }
 253  6
                 returnMessage = invoker.execute();
 254  
 
 255  
                 // stats
 256  6
                 if (stat.isEnabled())
 257  
                 {
 258  0
                     stat.addExecutionTime(System.currentTimeMillis() - startTime);
 259  
                 }
 260  
                 // this is the request event
 261  6
                 event = RequestContext.getEvent();
 262  6
                 if (event.isStopFurtherProcessing())
 263  
                 {
 264  0
                     logger.debug("Event stop further processing has been set, no outbound routing will be performed.");
 265  
                 }
 266  6
                 if (returnMessage != null && !event.isStopFurtherProcessing())
 267  
                 {
 268  4
                     if (descriptor.getOutboundRouter().hasEndpoints())
 269  
                     {
 270  0
                         UMOMessage outboundReturnMessage = descriptor.getOutboundRouter().route(
 271  
                             returnMessage, event.getSession(), event.isSynchronous());
 272  0
                         if (outboundReturnMessage != null)
 273  
                         {
 274  0
                             returnMessage = outboundReturnMessage;
 275  
                         }
 276  0
                     }
 277  
                     else
 278  
                     {
 279  4
                         logger.debug("Outbound router on component '" + descriptor.getName()
 280  
                                      + "' doesn't have any endpoints configured.");
 281  
                     }
 282  
                 }
 283  
 
 284  
                 // Process Response Router
 285  6
                 if (returnMessage != null && descriptor.getResponseRouter() != null)
 286  
                 {
 287  0
                     logger.debug("Waiting for response router message");
 288  0
                     returnMessage = descriptor.getResponseRouter().getResponse(returnMessage);
 289  
                 }
 290  
 
 291  
                 // process replyTo if there is one
 292  6
                 if (returnMessage != null && replyToHandler != null)
 293  
                 {
 294  0
                     String requestor = (String) returnMessage.getProperty(MuleProperties.MULE_REPLY_TO_REQUESTOR_PROPERTY);
 295  0
                     if ((requestor != null && !requestor.equals(descriptor.getName())) || requestor == null)
 296  
                     {
 297  0
                         replyToHandler.processReplyTo(event, returnMessage, replyTo);
 298  
                     }
 299  
                 }
 300  
 
 301  6
             }
 302  
             else
 303  
             {
 304  2
                 returnMessage = event.getSession().sendEvent(event);
 305  2
                 processReplyTo(returnMessage);
 306  
             }
 307  
 
 308  
             // stats
 309  8
             if (stat.isEnabled())
 310  
             {
 311  0
                 stat.incSentEventSync();
 312  
             }
 313  
         }
 314  0
         catch (Exception e)
 315  
         {
 316  0
             event.getSession().setValid(false);
 317  0
             if (e instanceof MessagingException)
 318  
             {
 319  0
                 handleException(e);
 320  
             }
 321  
             else
 322  
             {
 323  0
                 handleException(
 324  
                     new MessagingException(
 325  
                         CoreMessages.eventProcessingFailedFor(descriptor.getName()), 
 326  
                         event.getMessage(), e));
 327  
             }
 328  
 
 329  0
             if (returnMessage == null)
 330  
             {
 331  0
                 returnMessage = new MuleMessage(NullPayload.getInstance(), (Map) null);
 332  
             }
 333  0
             UMOExceptionPayload exceptionPayload = RequestContext.getExceptionPayload();
 334  0
             if (exceptionPayload == null)
 335  
             {
 336  0
                 exceptionPayload = new ExceptionPayload(e);
 337  
             }
 338  0
             returnMessage.setExceptionPayload(exceptionPayload);
 339  8
         }
 340  8
         return returnMessage;
 341  
     }
 342  
 
 343  
     /**
 344  
      * When an exception occurs this method can be called to invoke the configured
 345  
      * UMOExceptionStrategy on the UMO
 346  
      * 
 347  
      * @param exception If the UMOExceptionStrategy implementation fails
 348  
      */
 349  
     public void handleException(Exception exception)
 350  
     {
 351  0
         descriptor.getExceptionListener().exceptionThrown(exception);
 352  0
     }
 353  
 
 354  
     public String toString()
 355  
     {
 356  0
         return "proxy for: " + descriptor.toString();
 357  
     }
 358  
 
 359  
     /**
 360  
      * Determines if the proxy is suspended
 361  
      * 
 362  
      * @return true if the proxy (and the UMO) are suspended
 363  
      */
 364  
     public boolean isSuspended()
 365  
     {
 366  0
         return suspended;
 367  
     }
 368  
 
 369  
     /**
 370  
      * Controls the suspension of the UMO event processing
 371  
      */
 372  
     public void suspend()
 373  
     {
 374  6
         suspended = true;
 375  6
     }
 376  
 
 377  
     /**
 378  
      * Triggers the UMO to resume processing of events if it is suspended
 379  
      */
 380  
     public void resume()
 381  
     {
 382  10
         suspended = false;
 383  10
     }
 384  
 
 385  
     protected ReplyToHandler getReplyToHandler(UMOMessage message, UMOImmutableEndpoint endpoint)
 386  
     {
 387  6
         Object replyTo = message.getReplyTo();
 388  6
         ReplyToHandler replyToHandler = null;
 389  6
         if (replyTo != null)
 390  
         {
 391  0
             replyToHandler = ((AbstractConnector) endpoint.getConnector()).getReplyToHandler();
 392  
             // Use the response transformer for the event if one is set
 393  0
             if (endpoint.getResponseTransformer() != null)
 394  
             {
 395  0
                 replyToHandler.setTransformer(endpoint.getResponseTransformer());
 396  
             }
 397  
         }
 398  6
         return replyToHandler;
 399  
     }
 400  
 
 401  
     private void processReplyTo(UMOMessage returnMessage) throws UMOException
 402  
     {
 403  2
         if (returnMessage != null && returnMessage.getReplyTo() != null)
 404  
         {
 405  0
             if (logger.isDebugEnabled())
 406  
             {
 407  0
                 logger.debug("sending reply to: " + returnMessage.getReplyTo());
 408  
             }
 409  
 
 410  0
             UMOEndpointURI endpointUri = new MuleEndpointURI(returnMessage.getReplyTo().toString());
 411  
 
 412  
             // get the endpointUri for this uri
 413  0
             UMOEndpoint endpoint = MuleEndpoint.getOrCreateEndpointForUri(endpointUri,
 414  
                 UMOEndpoint.ENDPOINT_TYPE_SENDER);
 415  
 
 416  
             // make sure remove the replyTo property as not cause a a forever
 417  
             // replyto loop
 418  0
             returnMessage.removeProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
 419  
 
 420  
             // Create the replyTo event asynchronous
 421  0
             UMOEvent replyToEvent = new MuleEvent(returnMessage, endpoint, event.getSession(), false);
 422  
 
 423  
             // queue the event
 424  0
             onEvent(queueSession, replyToEvent);
 425  
 
 426  0
             if (logger.isDebugEnabled())
 427  
             {
 428  0
                 logger.debug("reply to sent: " + returnMessage.getReplyTo());
 429  
             }
 430  
 
 431  0
             if (stat.isEnabled())
 432  
             {
 433  0
                 stat.incSentReplyToEvent();
 434  
             }
 435  
         }
 436  2
     }
 437  
 
 438  
     /**
 439  
      * This is the entry point for the thread that runs an asynchronous
 440  
      * component request. This method executes the request and
 441  
      * <p>
 442  
      * <b>NOTE:</b> It is the responsibility of the creator of this proxy to
 443  
      * release it (e.g., return it to the object pool), once this method has
 444  
      * completed.
 445  
      */
 446  
     public void run()
 447  
     {
 448  0
         if (logger.isTraceEnabled())
 449  
         {
 450  0
             logger.trace("MuleProxy: async onEvent for Mule UMO " + descriptor.getName());
 451  
         }
 452  
 
 453  
         try
 454  
         {
 455  0
             if (event.getEndpoint().canReceive())
 456  
             {
 457  
                 // dispatch the next receiver
 458  0
                 event = OptimizedRequestContext.criticalSetEvent(event);
 459  0
                 Object replyTo = event.getMessage().getReplyTo();
 460  0
                 ReplyToHandler replyToHandler = getReplyToHandler(event.getMessage(), event.getEndpoint());
 461  0
                 InterceptorsInvoker invoker =
 462  
                         new InterceptorsInvoker(interceptorList, descriptor,  event.getMessage());
 463  
 
 464  
                 // do stats
 465  0
                 long startTime = 0;
 466  0
                 if (stat.isEnabled())
 467  
                 {
 468  0
                     startTime = System.currentTimeMillis();
 469  
                 }
 470  0
                 UMOMessage result = invoker.execute();
 471  0
                 if (stat.isEnabled())
 472  
                 {
 473  0
                     stat.addExecutionTime(System.currentTimeMillis() - startTime);
 474  
                 }
 475  
                 // processResponse(result, replyTo, replyToHandler);
 476  0
                 event = RequestContext.getEvent();
 477  0
                 if (result != null && !event.isStopFurtherProcessing())
 478  
                 {
 479  0
                     descriptor.getOutboundRouter().route(result, event.getSession(), event.isSynchronous());
 480  
                 }
 481  
 
 482  
                 // process replyTo if there is one
 483  0
                 if (result != null && replyToHandler != null)
 484  
                 {
 485  0
                     String requestor = (String) result.getProperty(MuleProperties.MULE_REPLY_TO_REQUESTOR_PROPERTY);
 486  0
                     if ((requestor != null && !requestor.equals(descriptor.getName())) || requestor == null)
 487  
                     {
 488  0
                         replyToHandler.processReplyTo(event, result, replyTo);
 489  
                     }
 490  
                 }
 491  0
             }
 492  
             else
 493  
             {
 494  0
                 event.getEndpoint().dispatch(event);
 495  
             }
 496  
 
 497  0
             if (stat.isEnabled())
 498  
             {
 499  0
                 stat.incSentEventASync();
 500  
             }
 501  
         }
 502  0
         catch (Exception e)
 503  
         {
 504  0
             event.getSession().setValid(false);
 505  0
             if (e instanceof MessagingException)
 506  
             {
 507  0
                 handleException(e);
 508  
             }
 509  
             else
 510  
             {
 511  0
                 handleException(
 512  
                     new MessagingException(
 513  
                         CoreMessages.eventProcessingFailedFor(descriptor.getName()), 
 514  
                         event.getMessage(), e));
 515  
             }
 516  0
         }
 517  0
     }
 518  
     
 519  
     public void release()
 520  
     {
 521  
         // nothing to do
 522  0
     }
 523  
 
 524  
     public UMOImmutableDescriptor getDescriptor()
 525  
     {
 526  2
         return descriptor;
 527  
     }
 528  
 }