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