KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > servicemix > http > jetty > JettyContextManager


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.servicemix.http.jetty;
18
19 import java.io.IOException JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.net.InetAddress JavaDoc;
22 import java.net.URL JavaDoc;
23 import java.net.UnknownHostException JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Set JavaDoc;
28
29 import javax.jbi.JBIException;
30 import javax.management.MBeanServer JavaDoc;
31 import javax.servlet.ServletException JavaDoc;
32 import javax.servlet.http.HttpServletRequest JavaDoc;
33 import javax.servlet.http.HttpServletResponse JavaDoc;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.servicemix.http.ContextManager;
38 import org.apache.servicemix.http.HttpBridgeServlet;
39 import org.apache.servicemix.http.HttpConfiguration;
40 import org.apache.servicemix.http.HttpProcessor;
41 import org.apache.servicemix.http.SslParameters;
42 import org.mortbay.component.AbstractLifeCycle;
43 import org.mortbay.jetty.AbstractConnector;
44 import org.mortbay.jetty.Connector;
45 import org.mortbay.jetty.Handler;
46 import org.mortbay.jetty.HttpConnection;
47 import org.mortbay.jetty.HttpMethods;
48 import org.mortbay.jetty.MimeTypes;
49 import org.mortbay.jetty.Server;
50 import org.mortbay.jetty.handler.AbstractHandler;
51 import org.mortbay.jetty.handler.ContextHandler;
52 import org.mortbay.jetty.handler.ContextHandlerCollection;
53 import org.mortbay.jetty.handler.HandlerCollection;
54 import org.mortbay.jetty.security.Constraint;
55 import org.mortbay.jetty.security.ConstraintMapping;
56 import org.mortbay.jetty.security.SecurityHandler;
57 import org.mortbay.jetty.security.SslSocketConnector;
58 import org.mortbay.jetty.servlet.ServletHandler;
59 import org.mortbay.jetty.servlet.ServletHolder;
60 import org.mortbay.jetty.servlet.ServletMapping;
61 import org.mortbay.management.MBeanContainer;
62 import org.mortbay.thread.BoundedThreadPool;
63 import org.mortbay.thread.ThreadPool;
64 import org.mortbay.util.ByteArrayISO8859Writer;
65 import org.mortbay.util.LazyList;
66 import org.mortbay.util.StringUtil;
67 import org.springframework.core.io.ClassPathResource;
68
69 public class JettyContextManager implements ContextManager {
70
71     private static final Log logger = LogFactory.getLog(JettyContextManager.class);
72     
73     private Map JavaDoc servers;
74     private HttpConfiguration configuration;
75     private BoundedThreadPool threadPool;
76     private Map JavaDoc sslParams;
77     private MBeanServer JavaDoc mbeanServer;
78     private MBeanContainer mbeanContainer;
79     
80     /**
81      * @return the mbeanServer
82      */

83     public MBeanServer JavaDoc getMBeanServer() {
84         return mbeanServer;
85     }
86
87     /**
88      * @param mbeanServer the mbeanServer to set
89      */

90     public void setMBeanServer(MBeanServer JavaDoc mbeanServer) {
91         this.mbeanServer = mbeanServer;
92     }
93
94     public void init() throws Exception JavaDoc {
95         if (configuration == null) {
96             configuration = new HttpConfiguration();
97         }
98         if (mbeanServer != null && !configuration.isManaged() && configuration.isJettyManagement()) {
99             mbeanContainer = new MBeanContainer(mbeanServer);
100         }
101         servers = new HashMap JavaDoc();
102         sslParams = new HashMap JavaDoc();
103         BoundedThreadPool btp = new BoundedThreadPool();
104         btp.setMaxThreads(this.configuration.getJettyThreadPoolSize());
105         threadPool = btp;
106     }
107
108     public void shutDown() throws Exception JavaDoc {
109         stop();
110     }
111
112     public void start() throws Exception JavaDoc {
113         threadPool.start();
114         for (Iterator JavaDoc it = servers.values().iterator(); it.hasNext();) {
115             Server JavaDoc server = (Server JavaDoc) it.next();
116             server.start();
117         }
118     }
119
120     public void stop() throws Exception JavaDoc {
121         for (Iterator JavaDoc it = servers.values().iterator(); it.hasNext();) {
122             Server JavaDoc server = (Server JavaDoc) it.next();
123             server.stop();
124         }
125         for (Iterator JavaDoc it = servers.values().iterator(); it.hasNext();) {
126             Server JavaDoc server = (Server JavaDoc) it.next();
127             server.join();
128             Connector[] connectors = server.getConnectors();
129             for (int i = 0; i < connectors.length; i++) {
130                 if (connectors[i] instanceof AbstractConnector) {
131                     ((AbstractConnector) connectors[i]).join();
132                 }
133             }
134         }
135         threadPool.stop();
136     }
137     
138     public synchronized Object JavaDoc createContext(String JavaDoc strUrl,
139                                                      HttpProcessor processor) throws Exception JavaDoc {
140         URL JavaDoc url = new URL JavaDoc(strUrl);
141         Server JavaDoc server = getServer(url);
142         if (server == null) {
143             server = createServer(url, processor.getSsl());
144         } else {
145             // Check ssl params
146
SslParameters ssl = (SslParameters) sslParams.get(getKey(url));
147             if (ssl != null && !ssl.equals(processor.getSsl())) {
148                 throw new Exception JavaDoc("An https server is already created on port " + url.getPort() + " but SSL parameters do not match");
149             }
150         }
151         String JavaDoc path = url.getPath();
152         if (!path.startsWith("/")) {
153             path = "/" + path;
154         }
155         if (path.endsWith("/")) {
156             path = path.substring(0, path.length() - 1);
157         }
158         // Check that context does not exist yet
159
HandlerCollection handlerCollection = (HandlerCollection) server.getHandler();
160         ContextHandlerCollection contexts = (ContextHandlerCollection) handlerCollection.getHandlers()[0];
161         Handler[] handlers = contexts.getHandlers();
162         if (handlers != null) {
163             for (int i = 0; i < handlers.length; i++) {
164                 if (handlers[i] instanceof ContextHandler) {
165                     ContextHandler h = (ContextHandler) handlers[i];
166                     if (h.getContextPath().startsWith(path) ||
167                         path.startsWith(h.getContextPath())) {
168                         throw new Exception JavaDoc("The requested context for path '" + path + "' overlaps with an existing context for path: '" + h.getContextPath() + "'");
169                     }
170                 }
171             }
172         }
173         // Create context
174
ContextHandler context = new ContextHandler();
175         context.setContextPath(path);
176         ServletHolder holder = new ServletHolder();
177         holder.setName("jbiServlet");
178         holder.setClassName(HttpBridgeServlet.class.getName());
179         ServletHandler handler = new ServletHandler();
180         handler.setServlets(new ServletHolder[] { holder });
181         ServletMapping mapping = new ServletMapping();
182         mapping.setServletName("jbiServlet");
183         mapping.setPathSpec("/*");
184         handler.setServletMappings(new ServletMapping[] { mapping });
185         if (processor.getAuthMethod() != null) {
186             SecurityHandler secHandler = new SecurityHandler();
187             ConstraintMapping constraintMapping = new ConstraintMapping();
188             Constraint constraint = new Constraint();
189             constraint.setAuthenticate(true);
190             constraint.setRoles(new String JavaDoc[] { "*" });
191             constraintMapping.setConstraint(constraint);
192             constraintMapping.setPathSpec("/");
193             secHandler.setConstraintMappings(new ConstraintMapping[] { constraintMapping });
194             secHandler.setHandler(handler);
195             secHandler.setAuthMethod(processor.getAuthMethod());
196             secHandler.setUserRealm(new JaasUserRealm());
197             context.setHandler(secHandler);
198         } else {
199             context.setHandler(handler);
200         }
201         context.setAttribute("processor", processor);
202         // add context
203
contexts.addHandler(context);
204         context.start();
205         return context;
206     }
207     
208     public synchronized void remove(Object JavaDoc context) throws Exception JavaDoc {
209         ((ContextHandler) context).stop();
210         for (Iterator JavaDoc it = servers.values().iterator(); it.hasNext();) {
211             Server JavaDoc server = (Server JavaDoc) it.next();
212             HandlerCollection handlerCollection = (HandlerCollection) server.getHandler();
213             ContextHandlerCollection contexts = (ContextHandlerCollection) handlerCollection.getHandlers()[0];
214             Handler[] handlers = contexts.getHandlers();
215             if (handlers != null && handlers.length > 0) {
216                 contexts.setHandlers((Handler[])LazyList.removeFromArray(handlers, context));
217             }
218         }
219     }
220
221     protected Server JavaDoc getServer(URL JavaDoc url) {
222         Server JavaDoc server = (Server JavaDoc) servers.get(getKey(url));
223         return server;
224     }
225     
226     protected String JavaDoc getKey(URL JavaDoc url) {
227         String JavaDoc host = url.getHost();
228         try {
229             InetAddress JavaDoc addr = InetAddress.getByName(host);
230             if (addr.isAnyLocalAddress()) {
231                 host = InetAddress.getLocalHost().getHostName();
232             }
233         } catch (UnknownHostException JavaDoc e) {
234         }
235         String JavaDoc key = url.getProtocol() + "://" + host + ":" + url.getPort();
236         return key;
237     }
238     
239     protected Server JavaDoc createServer(URL JavaDoc url, SslParameters ssl) throws Exception JavaDoc {
240         boolean isSsl = false;
241         if (url.getProtocol().equals("https")) {
242             // TODO: put ssl default information on HttpConfiguration
243
if (ssl == null) {
244                 throw new IllegalArgumentException JavaDoc("https protocol required but no ssl parameters found");
245             }
246             isSsl = true;
247         } else if (!url.getProtocol().equals("http")) {
248             throw new UnsupportedOperationException JavaDoc("Protocol " + url.getProtocol() + " is not supported");
249         }
250         // Create a new server
251
Connector connector;
252         if (isSsl && ssl.isManaged()) {
253             String JavaDoc keyStore = ssl.getKeyStore();
254             if (keyStore == null) {
255                 throw new IllegalArgumentException JavaDoc("keyStore must be set");
256             }
257             ServiceMixSslSocketConnector sslConnector = new ServiceMixSslSocketConnector();
258             sslConnector.setSslKeyManagerFactoryAlgorithm(ssl.getKeyManagerFactoryAlgorithm());
259             sslConnector.setSslTrustManagerFactoryAlgorithm(ssl.getTrustManagerFactoryAlgorithm());
260             sslConnector.setProtocol(ssl.getProtocol());
261             sslConnector.setConfidentialPort(url.getPort());
262             sslConnector.setKeystore(keyStore);
263             sslConnector.setKeyAlias(ssl.getKeyAlias());
264             sslConnector.setTrustStore(ssl.getTrustStore());
265             sslConnector.setNeedClientAuth(ssl.isNeedClientAuth());
266             sslConnector.setWantClientAuth(ssl.isWantClientAuth());
267             sslConnector.setKeystoreManager(getConfiguration().getKeystoreManager());
268             connector = sslConnector;
269         } else if (isSsl) {
270             String JavaDoc keyStore = ssl.getKeyStore();
271             if (keyStore == null) {
272                 keyStore = System.getProperty("javax.net.ssl.keyStore", "");
273                 if (keyStore == null) {
274                     throw new IllegalArgumentException JavaDoc("keyStore or system property javax.net.ssl.keyStore must be set");
275                 }
276             }
277             if (keyStore.startsWith("classpath:")) {
278                 try {
279                     String JavaDoc res = keyStore.substring(10);
280                     URL JavaDoc resurl = new ClassPathResource(res).getURL();
281                     keyStore = resurl.toString();
282                 } catch (IOException JavaDoc e) {
283                     throw new JBIException("Unable to find keystore " + keyStore, e);
284                 }
285             }
286             String JavaDoc keyStorePassword = ssl.getKeyStorePassword();
287             if (keyStorePassword == null) {
288                 keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
289                 if (keyStorePassword == null) {
290                     throw new IllegalArgumentException JavaDoc("keyStorePassword or system property javax.net.ssl.keyStorePassword must be set");
291                 }
292             }
293             SslSocketConnector sslConnector = new SslSocketConnector();
294             sslConnector.setSslKeyManagerFactoryAlgorithm(ssl.getKeyManagerFactoryAlgorithm());
295             sslConnector.setSslTrustManagerFactoryAlgorithm(ssl.getTrustManagerFactoryAlgorithm());
296             sslConnector.setProtocol(ssl.getProtocol());
297             sslConnector.setConfidentialPort(url.getPort());
298             sslConnector.setPassword(ssl.getKeyStorePassword());
299             sslConnector.setKeyPassword(ssl.getKeyPassword() != null ? ssl.getKeyPassword() : keyStorePassword);
300             sslConnector.setKeystore(keyStore);
301             sslConnector.setKeystoreType(ssl.getKeyStoreType());
302             sslConnector.setNeedClientAuth(ssl.isNeedClientAuth());
303             sslConnector.setWantClientAuth(ssl.isWantClientAuth());
304             connector = sslConnector;
305         } else {
306             String JavaDoc connectorClassName = configuration.getJettyConnectorClassName();
307             try {
308                 connector = (Connector) Class.forName(connectorClassName).newInstance();
309             } catch (Exception JavaDoc e) {
310                 logger.warn("Could not create a jetty connector of class '" + connectorClassName + "'. Defaulting to " + HttpConfiguration.DEFAULT_JETTY_CONNECTOR_CLASS_NAME);
311                 if (logger.isDebugEnabled()) {
312                     logger.debug("Reason: " + e.getMessage(), e);
313                 }
314                 connector = (Connector) Class.forName(HttpConfiguration.DEFAULT_JETTY_CONNECTOR_CLASS_NAME).newInstance();
315             }
316         }
317         connector.setHost(url.getHost());
318         connector.setPort(url.getPort());
319         Server JavaDoc server = new Server JavaDoc();
320         server.setThreadPool(new ThreadPoolWrapper());
321         server.setConnectors(new Connector[] { connector });
322         ContextHandlerCollection contexts = new ContextHandlerCollection();
323         HandlerCollection handlers = new HandlerCollection();
324         handlers.setHandlers(new Handler[] { contexts, new DisplayServiceHandler() });
325         server.setHandler(handlers);
326         server.start();
327         servers.put(getKey(url), server);
328         sslParams.put(getKey(url), isSsl ? ssl : null);
329         if (mbeanContainer != null) {
330             server.getContainer().addEventListener(mbeanContainer);
331         }
332         return server;
333     }
334
335     public HttpConfiguration getConfiguration() {
336         return configuration;
337     }
338
339     public void setConfiguration(HttpConfiguration configuration) {
340         this.configuration = configuration;
341     }
342
343     public ThreadPool getThreadPool() {
344         return threadPool;
345     }
346     
347     protected class DisplayServiceHandler extends AbstractHandler {
348
349         public void handle(String JavaDoc target, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, int dispatch) throws IOException JavaDoc, ServletException JavaDoc {
350             if (response.isCommitted() || HttpConnection.getCurrentConnection().getRequest().isHandled())
351                 return;
352             
353             String JavaDoc method = request.getMethod();
354             
355             if (!method.equals(HttpMethods.GET) || !request.getRequestURI().equals("/")) {
356                 response.sendError(404);
357                 return;
358             }
359
360             response.setStatus(404);
361             response.setContentType(MimeTypes.TEXT_HTML);
362             
363             ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500);
364
365             String JavaDoc uri = request.getRequestURI();
366             uri = StringUtil.replace(uri, "<", "&lt;");
367             uri = StringUtil.replace(uri, ">", "&gt;");
368             
369             writer.write("<HTML>\n<HEAD>\n<TITLE>Error 404 - Not Found");
370             writer.write("</TITLE>\n<BODY>\n<H2>Error 404 - Not Found.</H2>\n");
371             writer.write("No service matched or handled this request.<BR>");
372             writer.write("Known services are: <ul>");
373
374             Set JavaDoc servers = JettyContextManager.this.servers.keySet();
375             for (Iterator JavaDoc iter = servers.iterator(); iter.hasNext();) {
376                 String JavaDoc serverUri = (String JavaDoc) iter.next();
377                 Server JavaDoc server = (Server JavaDoc) JettyContextManager.this.servers.get(serverUri);
378                 Handler[] handlers = server.getChildHandlersByClass(ContextHandler.class);
379                 for (int i = 0; handlers != null && i < handlers.length; i++) {
380                     if (!(handlers[i] instanceof ContextHandler)) {
381                         continue;
382                     }
383                     ContextHandler context = (ContextHandler) handlers[i];
384                     if (context.isStarted()) {
385                         writer.write("<li><a HREF=\"");
386                         writer.write(serverUri);
387                         if (!context.getContextPath().startsWith("/")) {
388                             writer.write("/");
389                         }
390                         writer.write(context.getContextPath());
391                         if (!context.getContextPath().endsWith("/")) {
392                             writer.write("/");
393                         }
394                         writer.write("?wsdl\">");
395                         writer.write(serverUri);
396                         writer.write(context.getContextPath());
397                         writer.write("</a></li>\n");
398                     } else {
399                         writer.write("<li>");
400                         writer.write(serverUri);
401                         writer.write(context.getContextPath());
402                         writer.write(" [Stopped]</li>\n");
403                     }
404                 }
405             }
406             
407             for (int i=0; i < 10; i++) {
408                 writer.write("\n<!-- Padding for IE -->");
409             }
410             
411             writer.write("\n</BODY>\n</HTML>\n");
412             writer.flush();
413             response.setContentLength(writer.size());
414             OutputStream JavaDoc out = response.getOutputStream();
415             writer.writeTo(out);
416             out.close();
417         }
418         
419     }
420     
421     protected class ThreadPoolWrapper extends AbstractLifeCycle implements ThreadPool {
422
423         public boolean dispatch(Runnable JavaDoc job) {
424             if (logger.isDebugEnabled()) {
425                 logger.debug("Dispatching job: " + job);
426             }
427             return threadPool.dispatch(job);
428         }
429
430         public int getIdleThreads() {
431             return threadPool.getIdleThreads();
432         }
433
434         public int getThreads() {
435             return threadPool.getThreads();
436         }
437
438         public void join() throws InterruptedException JavaDoc {
439         }
440
441         public boolean isLowOnThreads() {
442             return threadPool.isLowOnThreads();
443         }
444     }
445
446     public HttpProcessor getMainProcessor() {
447         throw new IllegalStateException JavaDoc("ServerManager is not managed");
448     }
449     
450 }
451
Popular Tags