View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.processor;
8   
9   import org.mule.api.MessagingException;
10  import org.mule.api.MuleEvent;
11  import org.mule.api.MuleException;
12  import org.mule.api.config.ThreadingProfile;
13  import org.mule.api.context.WorkManager;
14  import org.mule.api.context.WorkManagerSource;
15  import org.mule.api.lifecycle.Startable;
16  import org.mule.api.lifecycle.Stoppable;
17  import org.mule.api.processor.MessageProcessor;
18  import org.mule.config.i18n.CoreMessages;
19  import org.mule.work.AbstractMuleEventWork;
20  import org.mule.work.MuleWorkManager;
21  
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /**
29   * Processes {@link MuleEvent}'s asynchronously using a {@link MuleWorkManager} to schedule asynchronous
30   * processing of MessageProcessor delegate configured the next {@link MessageProcessor}. The next {@link MessageProcessor} is therefore be executed
31   * in a different thread regardless of the exchange-pattern configured on the inbound endpoint. If a
32   * transaction is present then an exception is thrown.
33   */
34  public class AsyncDelegateMessageProcessor extends AbstractMessageProcessorOwner
35      implements MessageProcessor, Startable, Stoppable
36  {
37      protected Log logger = LogFactory.getLog(getClass());
38  
39      protected WorkManagerSource workManagerSource;
40      protected boolean doThreading = true;
41      protected WorkManager workManager;
42      protected MessageProcessor delegate;
43  
44      public AsyncDelegateMessageProcessor(ThreadingProfile threadingProfile, String name, int shutdownTimeout)
45      {
46          this.doThreading = threadingProfile.isDoThreading();
47          workManager = threadingProfile.createWorkManager(name, shutdownTimeout);
48          workManagerSource = new WorkManagerSource()
49          {
50              public WorkManager getWorkManager() throws MuleException
51              {
52                  return workManager;
53              }
54          };
55      }
56  
57      public void start() throws MuleException
58      {
59          if (workManager != null)
60          {
61              workManager.start();
62          }
63          super.start();
64      }
65  
66      public void stop() throws MuleException
67      {
68          if (workManager != null)
69          {
70              workManager.dispose();
71          }
72          super.stop();
73      }
74  
75      public MuleEvent process(MuleEvent event) throws MuleException
76      {
77          // There is no need to copy the event here because it is copied in
78          // org.mule.work.AbstractMuleEventWork.run()
79          if (delegate != null)
80          {
81              try
82              {
83                  workManagerSource.getWorkManager().scheduleWork(new AsyncMessageProcessorWorker(event),
84                      WorkManager.INDEFINITE, null, new AsyncWorkListener(delegate));
85              }
86              catch (Exception e)
87              {
88                  new MessagingException(
89                      CoreMessages.errorSchedulingMessageProcessorForAsyncInvocation(delegate), event, e);
90              }
91          }
92          return event;
93      }
94  
95      public void setDelegate(MessageProcessor delegate)
96      {
97          this.delegate = delegate;
98      }
99  
100     @Override
101     protected List<MessageProcessor> getOwnedMessageProcessors()
102     {
103         return Collections.singletonList(delegate);
104     }
105 
106     class AsyncMessageProcessorWorker extends AbstractMuleEventWork
107     {
108         public AsyncMessageProcessorWorker(MuleEvent event)
109         {
110             super(event);
111         }
112 
113         @Override
114         protected void doRun()
115         {
116             try
117             {
118                 delegate.process(event);
119             }
120             catch (MuleException e)
121             {
122                 event.getFlowConstruct().getExceptionListener().handleException(e, event);
123             }
124         }
125     }
126 
127 }