View Javadoc

1   /*
2    * $Id: SedaService.java 22864 2011-09-05 17:18:46Z 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.model.seda;
12  
13  import org.mule.api.MuleContext;
14  import org.mule.api.MuleException;
15  import org.mule.api.config.ThreadingProfile;
16  import org.mule.api.lifecycle.InitialisationException;
17  import org.mule.api.processor.MessageProcessor;
18  import org.mule.api.processor.MessageProcessorChainBuilder;
19  import org.mule.config.ChainedThreadingProfile;
20  import org.mule.config.QueueProfile;
21  import org.mule.config.i18n.CoreMessages;
22  import org.mule.config.i18n.MessageFactory;
23  import org.mule.interceptor.ProcessingTimeInterceptor;
24  import org.mule.lifecycle.processor.ProcessIfStartedWaitIfSyncPausedMessageProcessor;
25  import org.mule.management.stats.ServiceStatistics;
26  import org.mule.processor.LaxSedaStageInterceptingMessageProcessor;
27  import org.mule.processor.SedaStageInterceptingMessageProcessor;
28  import org.mule.service.AbstractService;
29  import org.mule.service.processor.ServiceInternalMessageProcessor;
30  import org.mule.service.processor.ServiceLoggingMessageProcessor;
31  import org.mule.service.processor.ServiceOutboundMessageProcessor;
32  import org.mule.service.processor.ServiceOutboundStatisticsMessageProcessor;
33  import org.mule.service.processor.ServiceSetEventRequestContextMessageProcessor;
34  import org.mule.service.processor.ServiceStatisticsMessageProcessor;
35  import org.mule.util.concurrent.ThreadNameHelper;
36  
37  /**
38   * A Seda service runs inside a Seda Model and is responsible for managing a Seda
39   * Queue and thread pool for a Mule sevice service. In Seda terms this is equivilent
40   * to a stage.
41   */
42  public class SedaService extends AbstractService
43  {
44      /**
45       * Serial version/
46       */
47      private static final long serialVersionUID = 7711976708670893015L;
48  
49      /**
50       * The time out used for taking from the Seda Queue.
51       */
52      protected Integer queueTimeout;
53  
54      /**
55       * The threading profile to use for this service. If this is not set a default
56       * will be provided by the server
57       */
58      protected ThreadingProfile threadingProfile;
59  
60      /**
61       * The queue profile to use for this service. If this is not set a default will
62       * be provided by the server
63       */
64      protected QueueProfile queueProfile;
65  
66      protected SedaStageInterceptingMessageProcessor sedaStage;
67  
68      public SedaService(MuleContext muleContext)
69      {
70          super(muleContext);
71      }
72  
73      @Override
74      protected MessageProcessor getServiceStartedAssertingMessageProcessor()
75      {
76          return new ProcessIfStartedWaitIfSyncPausedMessageProcessor(this, lifecycleManager.getState());
77      }
78  
79      protected void addMessageProcessors(MessageProcessorChainBuilder builder)
80      {
81          builder.chain(new ProcessingTimeInterceptor(null, this));
82          builder.chain(new ServiceLoggingMessageProcessor(this));
83          builder.chain(new ServiceStatisticsMessageProcessor(this));
84          builder.chain(new ServiceSetEventRequestContextMessageProcessor());
85          if (getThreadingProfile().isDoThreading())
86          {
87              sedaStage = new LaxSedaStageInterceptingMessageProcessor(ThreadNameHelper.sedaService(
88                  muleContext, getName()), getName(), queueProfile, queueTimeout, threadingProfile, stats,
89                  muleContext);
90              builder.chain(sedaStage);
91          }
92          builder.chain(new ServiceInternalMessageProcessor(this));
93          if (asyncReplyMessageSource.getEndpoints().size() > 0)
94          {
95              builder.chain(createAsyncReplyProcessor());
96          }
97          builder.chain(new ServiceOutboundMessageProcessor(this));
98          builder.chain(new ServiceOutboundStatisticsMessageProcessor(this));
99          builder.chain(outboundRouter);
100     }
101 
102     /**
103      * Initialise the service. The service will first create a Mule component from
104      * the Service and then initialise a pool based on the attributes in the Service.
105      * 
106      * @throws org.mule.api.lifecycle.InitialisationException if the service fails to
107      *             initialise
108      */
109     @Override
110     protected synchronized void doInitialise() throws InitialisationException
111     {
112         if (threadingProfile == null)
113         {
114             threadingProfile = muleContext.getDefaultServiceThreadingProfile();
115         }
116         // Create thread pool
117         // (Add one to maximum number of active threads to account for the service
118         // work item that is running continuously and polling the SEDA queue.)
119         ChainedThreadingProfile threadingProfile = new ChainedThreadingProfile(this.threadingProfile);
120         threadingProfile.setMuleContext(muleContext);
121         threadingProfile.setMaxThreadsActive(threadingProfile.getMaxThreadsActive() + 1);
122         // TODO it would be nicer if the shutdown value was encapsulated in the
123         // Threading profile, but it is more difficult than it seems
124 
125         if (queueProfile == null && model != null)
126         {
127             queueProfile = ((SedaModel) model).getQueueProfile();
128         }
129         if (queueTimeout == null && model != null)
130         {
131             setQueueTimeout(((SedaModel) model).getQueueTimeout());
132         }
133         
134         try
135         {
136             if (name == null)
137             {
138                 throw new InitialisationException(
139                     MessageFactory.createStaticMessage("Service has no name to identify it"), this);
140             }
141         }
142         catch (Throwable e)
143         {
144             throw new InitialisationException(CoreMessages.objectFailedToInitialise("Service Queue"), e, this);
145         }
146         super.doInitialise();
147     }
148 
149     @Override
150     protected ServiceStatistics createStatistics()
151     {
152         return new ServiceStatistics(getName(), threadingProfile.getMaxThreadsActive());
153     }
154 
155     public QueueProfile getQueueProfile()
156     {
157         return queueProfile;
158     }
159 
160     public void setQueueProfile(QueueProfile queueProfile)
161     {
162         this.queueProfile = queueProfile;
163     }
164 
165     public Integer getQueueTimeout()
166     {
167         return queueTimeout;
168     }
169 
170     public void setQueueTimeout(Integer queueTimeout)
171     {
172         this.queueTimeout = queueTimeout;
173     }
174 
175     public ThreadingProfile getThreadingProfile()
176     {
177         return threadingProfile;
178     }
179 
180     public void setThreadingProfile(ThreadingProfile threadingProfile)
181     {
182         this.threadingProfile = threadingProfile;
183     }
184 
185     @Override
186     protected void doPause() throws MuleException
187     {
188         super.doPause();
189         sedaStage.pause();
190     }
191 
192     @Override
193     protected void doResume() throws MuleException
194     {
195         sedaStage.resume();
196         super.doResume();
197     }
198 
199 }