All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.conf.ReconfigurationServlet Maven / Gradle / Ivy

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

package org.apache.hadoop.conf;

import org.apache.commons.text.StringEscapeUtils;

import java.util.Collection;
import java.util.Enumeration;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.hadoop.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A servlet for changing a node's configuration.
 *
 * Reloads the configuration file, verifies whether changes are
 * possible and asks the admin to approve the change.
 *
 */
public class ReconfigurationServlet extends HttpServlet {
  
  private static final long serialVersionUID = 1L;

  private static final Logger LOG =
      LoggerFactory.getLogger(ReconfigurationServlet.class);

  // the prefix used to fing the attribute holding the reconfigurable 
  // for a given request
  //
  // we get the attribute prefix + servlet path
  public static final String CONF_SERVLET_RECONFIGURABLE_PREFIX =
    "conf.servlet.reconfigurable.";
  
  @Override
  public void init() throws ServletException {
    super.init();
  }

  private Reconfigurable getReconfigurable(HttpServletRequest req) {
    LOG.info("servlet path: " + req.getServletPath());
    LOG.info("getting attribute: " + CONF_SERVLET_RECONFIGURABLE_PREFIX +
             req.getServletPath());
    return (Reconfigurable)
      this.getServletContext().getAttribute(CONF_SERVLET_RECONFIGURABLE_PREFIX +
                                            req.getServletPath());
  }

  private void printHeader(PrintWriter out, String nodeName) {
    out.print("");
    out.printf("%s Reconfiguration Utility%n",
               StringEscapeUtils.escapeHtml4(nodeName));
    out.print("\n");
    out.printf("

%s Reconfiguration Utility

%n", StringEscapeUtils.escapeHtml4(nodeName)); } private void printFooter(PrintWriter out) { out.print("\n"); } /** * Print configuration options that can be changed. */ private void printConf(PrintWriter out, Reconfigurable reconf) { Configuration oldConf = reconf.getConf(); Configuration newConf = new Configuration(); Collection changes = ReconfigurationUtil.getChangedProperties(newConf, oldConf); boolean changeOK = true; out.println("
"); out.println(""); out.println(""); out.println(""); for (ReconfigurationUtil.PropertyChange c: changes) { out.print(""); out.print("\n"); } out.println("
PropertyOld valueNew value
"); if (!reconf.isPropertyReconfigurable(c.prop)) { out.print("" + StringEscapeUtils.escapeHtml4(c.prop) + ""); changeOK = false; } else { out.print(StringEscapeUtils.escapeHtml4(c.prop)); out.print(""); } out.print("" + (c.oldVal == null ? "default" : StringEscapeUtils.escapeHtml4(c.oldVal)) + "" + (c.newVal == null ? "default" : StringEscapeUtils.escapeHtml4(c.newVal)) + "
"); if (!changeOK) { out.println("

WARNING: properties marked red" + " will not be changed until the next restart.

"); } out.println(""); out.println("
"); } @SuppressWarnings("unchecked") private Enumeration getParams(HttpServletRequest req) { return req.getParameterNames(); } /** * Apply configuratio changes after admin has approved them. */ private void applyChanges(PrintWriter out, Reconfigurable reconf, HttpServletRequest req) throws ReconfigurationException { Configuration oldConf = reconf.getConf(); Configuration newConf = new Configuration(); Enumeration params = getParams(req); synchronized(oldConf) { while (params.hasMoreElements()) { String rawParam = params.nextElement(); String param = StringEscapeUtils.unescapeHtml4(rawParam); String value = StringEscapeUtils.unescapeHtml4(req.getParameter(rawParam)); if (value != null) { if (value.equals(newConf.getRaw(param)) || value.equals("default") || value.equals("null") || value.isEmpty()) { if ((value.equals("default") || value.equals("null") || value.isEmpty()) && oldConf.getRaw(param) != null) { out.println("

Changed \"" + StringEscapeUtils.escapeHtml4(param) + "\" from \"" + StringEscapeUtils.escapeHtml4(oldConf.getRaw(param)) + "\" to default

"); reconf.reconfigureProperty(param, null); } else if (!value.equals("default") && !value.equals("null") && !value.isEmpty() && (oldConf.getRaw(param) == null || !oldConf.getRaw(param).equals(value))) { // change from default or value to different value if (oldConf.getRaw(param) == null) { out.println("

Changed \"" + StringEscapeUtils.escapeHtml4(param) + "\" from default to \"" + StringEscapeUtils.escapeHtml4(value) + "\"

"); } else { out.println("

Changed \"" + StringEscapeUtils.escapeHtml4(param) + "\" from \"" + StringEscapeUtils.escapeHtml4(oldConf. getRaw(param)) + "\" to \"" + StringEscapeUtils.escapeHtml4(value) + "\"

"); } reconf.reconfigureProperty(param, value); } else { LOG.info("property " + param + " unchanged"); } } else { // parameter value != newConf value out.println("

\"" + StringEscapeUtils.escapeHtml4(param) + "\" not changed because value has changed from \"" + StringEscapeUtils.escapeHtml4(value) + "\" to \"" + StringEscapeUtils.escapeHtml4(newConf.getRaw(param)) + "\" since approval

"); } } } } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { LOG.info("GET"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); Reconfigurable reconf = getReconfigurable(req); String nodeName = reconf.getClass().getCanonicalName(); printHeader(out, nodeName); printConf(out, reconf); printFooter(out); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { LOG.info("POST"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); Reconfigurable reconf = getReconfigurable(req); String nodeName = reconf.getClass().getCanonicalName(); printHeader(out, nodeName); try { applyChanges(out, reconf, req); } catch (ReconfigurationException e) { resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringUtils.stringifyException(e)); return; } out.println("

back

"); printFooter(out); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy