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