View Javadoc

1   /*
2    * $Id: AsyncDelegateMessageProcessor.java 23126 2011-10-07 01:06:45Z dfeist $
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.MuleMessage;
18  import org.mule.api.ThreadSafeAccess;
19  import org.mule.api.lifecycle.Initialisable;
20  import org.mule.api.lifecycle.InitialisationException;
21  import org.mule.api.lifecycle.Startable;
22  import org.mule.api.lifecycle.Stoppable;
23  import org.mule.api.processor.MessageProcessor;
24  import org.mule.api.processor.MessageProcessorChainBuilder;
25  import org.mule.api.processor.ProcessingStrategy;
26  import org.mule.api.processor.ProcessingStrategy.StageNameSource;
27  import org.mule.config.i18n.CoreMessages;
28  import org.mule.construct.Flow;
29  import org.mule.processor.chain.DefaultMessageProcessorChainBuilder;
30  import org.mule.work.AbstractMuleEventWork;
31  import org.mule.work.MuleWorkManager;
32  
33  import java.util.Collections;
34  import java.util.List;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  /**
40   * Processes {@link MuleEvent}'s asynchronously using a {@link MuleWorkManager} to schedule asynchronous
41   * processing of MessageProcessor delegate configured the next {@link MessageProcessor}. The next
42   * {@link MessageProcessor} is therefore be executed in a different thread regardless of the exchange-pattern
43   * configured on the inbound endpoint. If a transaction is present then an exception is thrown.
44   */
45  public class AsyncDelegateMessageProcessor extends AbstractMessageProcessorOwner
46      implements MessageProcessor, Initialisable, Startable, Stoppable
47  {
48      protected Log logger = LogFactory.getLog(getClass());
49  
50      protected MessageProcessor delegate;
51  
52      protected List<MessageProcessor> processors;
53      protected ProcessingStrategy processingStrategy;
54      protected String name;
55  
56      private MessageProcessor target;
57  
58      public AsyncDelegateMessageProcessor(MessageProcessor delegate,
59                                           ProcessingStrategy processingStrategy,
60                                           String name)
61      {
62          this.delegate = delegate;
63          this.processingStrategy = processingStrategy;
64          this.name = name;
65      }
66  
67      @Override
68      public void initialise() throws InitialisationException
69      {
70          if (delegate == null)
71          {
72              throw new InitialisationException(CoreMessages.objectIsNull("delegate message processor"), this);
73          }
74          if (processingStrategy == null)
75          {
76              throw new InitialisationException(CoreMessages.objectIsNull("processingStrategy"), this);
77          }
78          StageNameSource nameSource = null;
79          if (name != null)
80          {
81              nameSource = ((Flow)flowConstruct).getAsyncStageNameSource(name);
82          }
83          else
84          {
85              nameSource = ((Flow)flowConstruct).getAsyncStageNameSource();
86          }
87  
88          MessageProcessorChainBuilder builder = new DefaultMessageProcessorChainBuilder(flowConstruct);
89          processingStrategy.configureProcessors(Collections.singletonList(delegate), nameSource, builder,
90              muleContext);
91          try
92          {
93              target = builder.build();
94          }
95          catch (MuleException e)
96          {
97              throw new InitialisationException(e, this);
98          }
99          super.initialise();
100     }
101 
102     public MuleEvent process(MuleEvent event) throws MuleException
103     {
104         if (event.isTransacted())
105         {
106             throw new MessagingException(CoreMessages.asyncDoesNotSupportTransactions(), event);
107         }
108 
109         if (target != null)
110         {
111             // Clone event and make it async
112             MuleEvent newEvent = new DefaultMuleEvent(
113                 (MuleMessage)((ThreadSafeAccess)event.getMessage()).newThreadCopy(), event, false);
114             target.process(newEvent);
115         }
116         return event;
117     }
118 
119     public void setDelegate(MessageProcessor delegate)
120     {
121         this.delegate = delegate;
122     }
123 
124     @Override
125     protected List<MessageProcessor> getOwnedMessageProcessors()
126     {
127         return Collections.singletonList(target);
128     }
129 
130     public ProcessingStrategy getProcessingStrategy()
131     {
132         return processingStrategy;
133     }
134 
135     class AsyncMessageProcessorWorker extends AbstractMuleEventWork
136     {
137         public AsyncMessageProcessorWorker(MuleEvent event)
138         {
139             super(event);
140         }
141 
142         @Override
143         protected void doRun()
144         {
145             try
146             {
147                 delegate.process(event);
148             }
149             catch (MuleException e)
150             {
151                 event.getFlowConstruct().getExceptionListener().handleException(e, event);
152             }
153         }
154     }
155 
156 }