View Javadoc

1   /*
2    * $Id: JettyHttpConnector.java 12320 2008-07-13 04:58:28Z rossmason $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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.transport.servlet.jetty;
12  
13  import org.mule.api.MuleException;
14  import org.mule.api.endpoint.EndpointURI;
15  import org.mule.api.lifecycle.InitialisationException;
16  import org.mule.api.lifecycle.LifecycleException;
17  import org.mule.api.transport.MessageReceiver;
18  import org.mule.api.transport.ReplyToHandler;
19  import org.mule.config.i18n.CoreMessages;
20  import org.mule.transport.AbstractConnector;
21  import org.mule.util.IOUtils;
22  
23  import java.io.InputStream;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.Map;
27  
28  import org.mortbay.jetty.Server;
29  import org.mortbay.jetty.nio.SelectChannelConnector;
30  import org.mortbay.jetty.servlet.ServletHandler;
31  import org.mortbay.jetty.servlet.ServletHolder;
32  import org.mortbay.xml.XmlConfiguration;
33  
34  /**
35   * The <code>JettyConnector</code> can be using to embed a Jetty server to receive requests on an http inound endpoint.
36   * One server is created for each connector declared, Many Jetty endpoints can share the same connector.
37   */
38  
39  public class JettyHttpConnector extends AbstractConnector
40  {
41  
42      public static final String JETTY = "jetty";
43      public static final String REST = "rest";
44  
45      private Server httpServer;
46  
47      private Map serverPorts;
48  
49      private String configFile;
50  
51      private JettyReceiverServlet receiverServlet;
52  
53      private Class servletClass;
54  
55      private ServletHolder holder;
56  
57      private boolean useContinuations = false;
58  
59      public JettyHttpConnector()
60      {
61          super();
62          registerSupportedProtocol("http");
63          registerSupportedProtocol(REST);
64          serverPorts = new HashMap(4);
65      }
66  
67      public String getProtocol()
68      {
69          return JETTY;
70      }
71  
72      //@Override
73      protected void doInitialise() throws InitialisationException
74      {
75          httpServer = new Server();
76  
77          if(getReceiverServlet()==null)
78          {
79              setServletClass((useContinuations ? JettyContinuationsReceiverServlet.class :
80                      JettyReceiverServlet.class));
81          }
82          
83          ServletHandler handler = new ServletHandler();
84          holder = handler.addServletWithMapping(getServletClass(), "/*");
85          
86          httpServer.addHandler(handler);
87          
88          if (configFile != null)
89          {
90              try
91              {
92                  InputStream is = IOUtils.getResourceAsStream(configFile, getClass());
93                  XmlConfiguration config = new XmlConfiguration(is);
94                  config.configure(httpServer);
95              }
96              catch (Exception e)
97              {
98                  throw new InitialisationException(e, this);
99              }
100         }
101     }
102 
103     /**
104      * Template method to dispose any resources associated with this receiver. There
105      * is not need to dispose the connector as this is already done by the framework
106      */
107     protected void doDispose()
108     {
109         try
110         {
111             httpServer.stop();
112         }
113         catch (Exception e)
114         {
115             logger.error("Error disposing Jetty server", e);
116         }
117         serverPorts.clear();
118     }
119 
120     protected void doStart() throws MuleException
121     {
122         try
123         {
124             httpServer.start();
125             receiverServlet = (JettyReceiverServlet)holder.getServlet();
126             for (Iterator iter = receivers.values().iterator(); iter.hasNext();)
127             {
128                 MessageReceiver receiver = (MessageReceiver) iter.next();
129                 receiverServlet.addReceiver(receiver);
130             }
131 
132         }
133         catch (Exception e)
134         {
135             throw new LifecycleException(CoreMessages.failedToStart("Jetty Http Receiver"), e, this);
136         }
137     }
138 
139     protected void doStop() throws MuleException
140     {
141         try
142         {
143             for (Iterator iter = receivers.values().iterator(); iter.hasNext();)
144             {
145                 MessageReceiver receiver = (MessageReceiver) iter.next();
146                 receiverServlet.removeReceiver(receiver);
147             }
148             httpServer.stop();
149             
150         }
151         catch (Exception e)
152         {
153             throw new LifecycleException(CoreMessages.failedToStop("Jetty Http Receiver"), e, this);
154         }
155     }
156 
157 
158     /**
159      * Template method where any connections should be made for the connector
160      *
161      * @throws Exception
162      */
163     protected void doConnect() throws Exception
164     {
165         //do nothing
166     }
167 
168     /**
169      * Template method where any connected resources used by the connector should be
170      * disconnected
171      *
172      * @throws Exception
173      */
174     protected void doDisconnect() throws Exception
175     {
176         //do nothing
177     }
178 
179 
180     void registerListener(MessageReceiver receiver) throws Exception
181     {
182         EndpointURI uri = receiver.getEndpointURI();
183         if (serverPorts.keySet().contains(new Integer(uri.getPort())))
184         {
185             logger.debug("Http server already listening on: " + uri.getPort());
186             receiverServlet.addReceiver(receiver);
187             return;
188         }
189 
190         //TODO
191 //        ThreadingProfile tp = getReceiverThreadingProfile();
192 //        getHttpServer().addConnector(socketListener);
193 //
194 //         QueuedThreadPool threadPool = new QueuedThreadPool();
195 //          threadPool.setMaxThreads(tp.getMaxThreadsActive());
196 //        threadPool.setMinThreads(tp.getMaxThreadsIdle());
197 //        threadPool.setMaxIdleTimeMs((int)tp.getThreadTTL());
198 //        //TODO exhaust action
199 //          httpServer.setThreadPool(threadPool);
200 
201         org.mortbay.jetty.AbstractConnector cnn = createJettyConnector();
202 
203         cnn.setPort(uri.getPort());
204 
205         httpServer.addConnector(cnn);
206 
207         serverPorts.put(new Integer(uri.getPort()), null);
208         receiverServlet.addReceiver(receiver);
209 
210         try
211         {
212 
213             cnn.start();
214         }
215         catch (Exception e)
216         {
217             e.printStackTrace();
218             throw e;
219         }
220     }
221 
222     protected org.mortbay.jetty.AbstractConnector createJettyConnector()
223     {
224         return new SelectChannelConnector();
225     }
226 
227     public boolean unregisterListener(MessageReceiver receiver)
228     {
229         return receiverServlet.removeReceiver(receiver);
230     }
231 
232 
233     public Server getHttpServer()
234     {
235         return httpServer;
236     }
237 
238     public String getConfigFile()
239     {
240         return configFile;
241     }
242 
243     public void setConfigFile(String configFile)
244     {
245         this.configFile = configFile;
246     }
247 
248     public JettyReceiverServlet getReceiverServlet()
249     {
250         return receiverServlet;
251     }
252 
253     public void setReceiverServlet(JettyReceiverServlet receiverServlet)
254     {
255         this.receiverServlet = receiverServlet;
256     }
257 
258     protected JettyReceiverServlet createReceiverServlet()
259     {
260         return new JettyReceiverServlet();
261     }
262 
263     public Class getServletClass()
264     {
265         return servletClass;
266     }
267 
268     public void setServletClass(Class servletClass)
269     {
270         this.servletClass = servletClass;
271     }
272 
273     /**
274      * Getter for property 'replyToHandler'.
275      *
276      * @return Value for property 'replyToHandler'.
277      */
278     //@Override
279     public ReplyToHandler getReplyToHandler()
280     {
281         if(isUseContinuations())
282         {
283             return new JettyContinuationsReplyToHandler(getDefaultResponseTransformers());
284         }
285         return super.getReplyToHandler();
286     }
287 
288     public boolean isUseContinuations()
289     {
290         return useContinuations;
291     }
292 
293     public void setUseContinuations(boolean useContinuations)
294     {
295         this.useContinuations = useContinuations;
296     }
297 }