Coverage Report - org.mule.processor.AsyncInterceptingMessageProcessor
 
Classes in this File Line Coverage Branch Coverage Complexity
AsyncInterceptingMessageProcessor
0%
0/61
0%
0/24
0
AsyncInterceptingMessageProcessor$1
0%
0/2
N/A
0
AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker
0%
0/8
N/A
0
 
 1  
 /*
 2  
  * $Id: AsyncInterceptingMessageProcessor.java 20343 2010-11-24 21:02:10Z mike.schilling $
 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.processor;
 12  
 
 13  
 import org.mule.DefaultMuleEvent;
 14  
 import org.mule.api.MessagingException;
 15  
 import org.mule.api.MuleEvent;
 16  
 import org.mule.api.MuleException;
 17  
 import org.mule.api.MuleRuntimeException;
 18  
 import org.mule.api.config.ThreadingProfile;
 19  
 import org.mule.api.context.WorkManager;
 20  
 import org.mule.api.context.WorkManagerSource;
 21  
 import org.mule.api.endpoint.OutboundEndpoint;
 22  
 import org.mule.api.lifecycle.Startable;
 23  
 import org.mule.api.lifecycle.Stoppable;
 24  
 import org.mule.api.processor.MessageProcessor;
 25  
 import org.mule.config.i18n.CoreMessages;
 26  
 import org.mule.interceptor.ProcessingTimeInterceptor;
 27  
 import org.mule.work.AbstractMuleEventWork;
 28  
 import org.mule.work.MuleWorkManager;
 29  
 
 30  
 import javax.resource.spi.work.WorkEvent;
 31  
 import javax.resource.spi.work.WorkListener;
 32  
 
 33  
 /**
 34  
  * Processes {@link MuleEvent}'s asynchronously using a {@link MuleWorkManager} to
 35  
  * schedule asynchronous processing of the next {@link MessageProcessor}. The next
 36  
  * {@link MessageProcessor} is therefore be executed in a different thread regardless
 37  
  * of the exchange-pattern configured on the inbound endpoint. If a transaction is
 38  
  * present then an exception is thrown.
 39  
  */
 40  
 public class AsyncInterceptingMessageProcessor extends AbstractInterceptingMessageProcessor
 41  
     implements WorkListener, Startable, Stoppable
 42  
 {
 43  
     protected WorkManagerSource workManagerSource;
 44  0
     protected boolean doThreading = true;
 45  
     protected WorkManager workManager;
 46  
 
 47  
     public AsyncInterceptingMessageProcessor(WorkManagerSource workManagerSource)
 48  0
     {
 49  0
         this.workManagerSource = workManagerSource;
 50  0
     }
 51  
 
 52  
     @Deprecated
 53  
     public AsyncInterceptingMessageProcessor(WorkManagerSource workManagerSource, boolean doThreading)
 54  0
     {
 55  0
         this.workManagerSource = workManagerSource;
 56  0
         this.doThreading = doThreading;
 57  0
     }
 58  
 
 59  
     public AsyncInterceptingMessageProcessor(ThreadingProfile threadingProfile,
 60  
                                              String name,
 61  
                                              int shutdownTimeout)
 62  0
     {
 63  0
         this.doThreading = threadingProfile.isDoThreading();
 64  0
         workManager = threadingProfile.createWorkManager(name, shutdownTimeout);
 65  0
         workManagerSource = new WorkManagerSource()
 66  0
         {
 67  
             public WorkManager getWorkManager() throws MuleException
 68  
             {
 69  0
                 return workManager;
 70  
             }
 71  
         };
 72  0
     }
 73  
 
 74  
     public void start() throws MuleException
 75  
     {
 76  0
         if (workManager != null)
 77  
         {
 78  0
             workManager.start();
 79  
         }
 80  0
     }
 81  
 
 82  
     public void stop() throws MuleException
 83  
     {
 84  0
         if (workManager != null)
 85  
         {
 86  0
             workManager.dispose();
 87  
         }
 88  0
     }
 89  
 
 90  
     public MuleEvent process(MuleEvent event) throws MuleException
 91  
     {
 92  0
         if (next == null)
 93  
         {
 94  0
             return event;
 95  
         }
 96  0
         else if (isProcessAsync(event))
 97  
         {
 98  0
             processNextAsync(event);
 99  0
             return null;
 100  
         }
 101  
         else
 102  
         {
 103  0
             MuleEvent response = processNext(event);
 104  0
             return response;
 105  
         }
 106  
     }
 107  
 
 108  
     protected MuleEvent processNextTimed(MuleEvent event) throws MuleException
 109  
     {
 110  0
         if (next == null)
 111  
         {
 112  0
             return event;
 113  
         }
 114  
         else
 115  
         {
 116  0
             if (logger.isTraceEnabled())
 117  
             {
 118  0
                 logger.trace("Invoking next MessageProcessor: '" + next.getClass().getName() + "' ");
 119  
             }
 120  
             // If the next message processor is an outbound router then create outbound event
 121  0
             if (next instanceof OutboundEndpoint)
 122  
             {
 123  0
                 event = new DefaultMuleEvent(event.getMessage(), (OutboundEndpoint) next, event.getSession());
 124  
             }
 125  
 
 126  
             MuleEvent response;
 127  0
             if (event.getFlowConstruct() != null)
 128  
             {
 129  0
                 response = new ProcessingTimeInterceptor(next, event.getFlowConstruct()).process(event);
 130  
             }
 131  
             else
 132  
             {
 133  0
                 response = next.process(event);
 134  
             }
 135  0
             return response;
 136  
         }
 137  
     }
 138  
 
 139  
     protected boolean isProcessAsync(MuleEvent event) throws MessagingException
 140  
     {
 141  
         // We do not support transactions and async
 142  0
         if (event.getEndpoint().getTransactionConfig().isTransacted())
 143  
         {
 144  0
             throw new MessagingException(CoreMessages.asyncDoesNotSupportTransactions(), event);
 145  
         }
 146  0
         return doThreading;
 147  
     }
 148  
 
 149  
     protected void processNextAsync(MuleEvent event) throws MuleException
 150  
     {
 151  
         try
 152  
         {
 153  0
             workManagerSource.getWorkManager().scheduleWork(new AsyncMessageProcessorWorker(event),
 154  
                 WorkManager.INDEFINITE, null, this);
 155  
         }
 156  0
         catch (Exception e)
 157  
         {
 158  0
             new MessagingException(CoreMessages.errorSchedulingMessageProcessorForAsyncInvocation(next),
 159  
                 event, e);
 160  0
         }
 161  0
     }
 162  
 
 163  
     public void workAccepted(WorkEvent event)
 164  
     {
 165  0
         this.handleWorkException(event, "workAccepted");
 166  0
     }
 167  
 
 168  
     public void workRejected(WorkEvent event)
 169  
     {
 170  0
         this.handleWorkException(event, "workRejected");
 171  0
     }
 172  
 
 173  
     public void workStarted(WorkEvent event)
 174  
     {
 175  0
         this.handleWorkException(event, "workStarted");
 176  0
     }
 177  
 
 178  
     public void workCompleted(WorkEvent event)
 179  
     {
 180  0
         this.handleWorkException(event, "workCompleted");
 181  0
     }
 182  
 
 183  
     protected void handleWorkException(WorkEvent event, String type)
 184  
     {
 185  0
         if (event == null)
 186  
         {
 187  0
             return;
 188  
         }
 189  
 
 190  0
         Throwable e = event.getException();
 191  
 
 192  0
         if (e == null)
 193  
         {
 194  0
             return;
 195  
         }
 196  
 
 197  0
         if (e.getCause() != null)
 198  
         {
 199  0
             e = e.getCause();
 200  
         }
 201  
 
 202  0
         logger.error("Work caused exception on '" + type + "'. Work being executed was: "
 203  
                      + event.getWork().toString());
 204  0
         throw new MuleRuntimeException(CoreMessages.errorInvokingMessageProcessorAsynchronously(next), e);
 205  
     }
 206  
 
 207  
     class AsyncMessageProcessorWorker extends AbstractMuleEventWork
 208  
     {
 209  
         public AsyncMessageProcessorWorker(MuleEvent event)
 210  0
         {
 211  0
             super(event);
 212  0
         }
 213  
 
 214  
         @Override
 215  
         protected void doRun()
 216  
         {
 217  
             try
 218  
             {
 219  0
                 processNextTimed(event);
 220  
             }
 221  0
             catch (MuleException e)
 222  
             {
 223  0
                 event.getFlowConstruct().getExceptionListener().handleException(e, event);
 224  0
             }
 225  0
         }
 226  
     }
 227  
 
 228  
 }