1 /**
2 * Copyright 2010 The Apache Software Foundation
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package org.apache.hadoop.hbase.util;
22
23 import org.apache.hadoop.http.HttpServer;
24 import org.mortbay.jetty.handler.ContextHandlerCollection;
25 import org.mortbay.jetty.servlet.Context;
26 import org.mortbay.jetty.servlet.DefaultServlet;
27
28 import java.io.IOException;
29 import java.net.URL;
30 import java.util.Map;
31
32 /**
33 * Create a Jetty embedded server to answer http requests. The primary goal
34 * is to serve up status information for the server.
35 * There are three contexts:
36 * "/stacks/" -> points to stack trace
37 * "/static/" -> points to common static files (src/hbase-webapps/static)
38 * "/" -> the jsp server code from (src/hbase-webapps/<name>)
39 */
40 public class InfoServer extends HttpServer {
41 /**
42 * Create a status server on the given port.
43 * The jsp scripts are taken from src/hbase-webapps/<code>name<code>.
44 * @param name The name of the server
45 * @param bindAddress address to bind to
46 * @param port The port to use on the server
47 * @param findPort whether the server should start at the given port and
48 * increment by 1 until it finds a free port.
49 * @throws IOException e
50 */
51 public InfoServer(String name, String bindAddress, int port, boolean findPort)
52 throws IOException {
53 super(name, bindAddress, port, findPort);
54 webServer.addHandler(new ContextHandlerCollection());
55 }
56
57 protected void addDefaultApps(ContextHandlerCollection parent, String appDir)
58 throws IOException {
59 super.addDefaultApps(parent, appDir);
60 // Must be same as up in hadoop.
61 final String logsContextPath = "/logs";
62 // Now, put my logs in place of hadoops... disable old one first.
63 Context oldLogsContext = null;
64 for (Map.Entry<Context, Boolean> e : defaultContexts.entrySet()) {
65 if (e.getKey().getContextPath().equals(logsContextPath)) {
66 oldLogsContext = e.getKey();
67 break;
68 }
69 }
70 if (oldLogsContext != null) {
71 this.defaultContexts.put(oldLogsContext, Boolean.FALSE);
72 }
73 // Now do my logs.
74 // set up the context for "/logs/" if "hadoop.log.dir" property is defined.
75 String logDir = System.getProperty("hbase.log.dir");
76 if (logDir != null) {
77 Context logContext = new Context(parent, "/logs");
78 logContext.setResourceBase(logDir);
79 logContext.addServlet(DefaultServlet.class, "/");
80 defaultContexts.put(logContext, true);
81 }
82 }
83
84 /**
85 * Get the pathname to the <code>path</code> files.
86 * @return the pathname as a URL
87 */
88 @Override
89 protected String getWebAppsPath() throws IOException {
90 // Hack: webapps is not a unique enough element to find in CLASSPATH
91 // We'll more than likely find the hadoop webapps dir. So, instead
92 // look for the 'master' webapp in the webapps subdir. That should
93 // get us the hbase context. Presumption is that place where the
94 // master webapp resides is where we want this InfoServer picking up
95 // web applications.
96 final String master = "master";
97 String p = getWebAppDir(master);
98 // Now strip master + the separator off the end of our context
99 return p.substring(0, p.length() - (master.length() + 1/* The separator*/));
100 }
101
102 private static String getWebAppsPath(final String path)
103 throws IOException {
104 URL url = InfoServer.class.getClassLoader().getResource(path);
105 if (url == null)
106 throw new IOException("hbase-webapps not found in CLASSPATH: " + path);
107 return url.toString();
108 }
109
110 /**
111 * Get the path for this web app
112 * @param webappName web app
113 * @return path
114 * @throws IOException e
115 */
116 public static String getWebAppDir(final String webappName)
117 throws IOException {
118 String webappDir;
119 webappDir = getWebAppsPath("hbase-webapps/" + webappName);
120 return webappDir;
121 }
122 }