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.hbase.HBaseConfiguration; 24 import org.apache.hadoop.http.HttpServer; 25 import org.mortbay.jetty.handler.ContextHandlerCollection; 26 import org.mortbay.jetty.servlet.Context; 27 import org.mortbay.jetty.servlet.DefaultServlet; 28 29 import java.io.IOException; 30 import java.net.URL; 31 import java.util.Map; 32 33 /** 34 * Create a Jetty embedded server to answer http requests. The primary goal 35 * is to serve up status information for the server. 36 * There are three contexts: 37 * "/stacks/" -> points to stack trace 38 * "/static/" -> points to common static files (src/hbase-webapps/static) 39 * "/" -> the jsp server code from (src/hbase-webapps/<name>) 40 */ 41 public class InfoServer extends HttpServer { 42 /** 43 * Create a status server on the given port. 44 * The jsp scripts are taken from src/hbase-webapps/<code>name<code>. 45 * @param name The name of the server 46 * @param bindAddress address to bind to 47 * @param port The port to use on the server 48 * @param findPort whether the server should start at the given port and 49 * increment by 1 until it finds a free port. 50 * @throws IOException e 51 */ 52 public InfoServer(String name, String bindAddress, int port, boolean findPort) 53 throws IOException { 54 super(name, bindAddress, port, findPort, HBaseConfiguration.create()); 55 webServer.addHandler(new ContextHandlerCollection()); 56 } 57 58 protected void addDefaultApps(ContextHandlerCollection parent, String appDir) 59 throws IOException { 60 super.addDefaultApps(parent, appDir); 61 // Must be same as up in hadoop. 62 final String logsContextPath = "/logs"; 63 // Now, put my logs in place of hadoops... disable old one first. 64 Context oldLogsContext = null; 65 for (Map.Entry<Context, Boolean> e : defaultContexts.entrySet()) { 66 if (e.getKey().getContextPath().equals(logsContextPath)) { 67 oldLogsContext = e.getKey(); 68 break; 69 } 70 } 71 if (oldLogsContext != null) { 72 this.defaultContexts.put(oldLogsContext, Boolean.FALSE); 73 } 74 // Now do my logs. 75 // set up the context for "/logs/" if "hadoop.log.dir" property is defined. 76 String logDir = System.getProperty("hbase.log.dir"); 77 if (logDir != null) { 78 Context logContext = new Context(parent, "/logs"); 79 logContext.setResourceBase(logDir); 80 logContext.addServlet(DefaultServlet.class, "/"); 81 defaultContexts.put(logContext, true); 82 } 83 } 84 85 /** 86 * Get the pathname to the <code>path</code> files. 87 * @return the pathname as a URL 88 */ 89 @Override 90 protected String getWebAppsPath() throws IOException { 91 // Hack: webapps is not a unique enough element to find in CLASSPATH 92 // We'll more than likely find the hadoop webapps dir. So, instead 93 // look for the 'master' webapp in the webapps subdir. That should 94 // get us the hbase context. Presumption is that place where the 95 // master webapp resides is where we want this InfoServer picking up 96 // web applications. 97 final String master = "master"; 98 String p = getWebAppDir(master); 99 // Now strip master + the separator off the end of our context 100 return p.substring(0, p.length() - (master.length() + 1/* The separator*/)); 101 } 102 103 private static String getWebAppsPath(final String path) 104 throws IOException { 105 URL url = InfoServer.class.getClassLoader().getResource(path); 106 if (url == null) 107 throw new IOException("hbase-webapps not found in CLASSPATH: " + path); 108 return url.toString(); 109 } 110 111 /** 112 * Get the path for this web app 113 * @param webappName web app 114 * @return path 115 * @throws IOException e 116 */ 117 public static String getWebAppDir(final String webappName) 118 throws IOException { 119 String webappDir; 120 webappDir = getWebAppsPath("hbase-webapps/" + webappName); 121 return webappDir; 122 } 123 }