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