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

com.ebay.jetstream.management.ManagementServlet Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *  Copyright © 2012-2015 eBay Software Foundation
 *  This program is dual licensed under the MIT and Apache 2.0 licenses.
 *  Please see LICENSE for more information.
 *******************************************************************************/
package com.ebay.jetstream.management;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jmx.export.annotation.ManagedResource;

import com.ebay.jetstream.util.CommonUtils;

@ManagedResource(objectName = "Meta/Management", description = "http object management interface")
public class ManagementServlet extends HttpServlet {
  private static final Logger LOGGER = LoggerFactory.getLogger(ManagementServlet.class.getName());
  private static final long serialVersionUID = 1L;
  private static int MAX_URL_LENGTH = 250;
  private Validator validator ;

static {
    Management.registerResourceFormatter("xml", XmlResourceFormatter.class);
    Management.registerResourceFormatter("spring", SpringResourceFormatter.class);
    Management.registerResourceFormatter("html", HtmlResourceFormatter.class);
    Management.registerResourceFormatter("json", JsonResourceFormatter.class);
    Management.registerResourceFormatter("help", HelpFormatter.class);
  }

  

  public ManagementServlet() {
    Management.addBean(toString(), this);
  }

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (!checkAuthorized(request, response, false))
      return;
    response.setCharacterEncoding("UTF-8");
    Map parameters = getParameterMap(request);
    boolean isHelp = parameters.remove("help") != null;
    if (isHelp && parameters.size() > 0) {
      sendError(response, HttpServletResponse.SC_BAD_REQUEST, "help cannot be combined with other parameters");
      return;
    }
    String format = getParameter(parameters, AbstractResourceFormatter.BEAN_FORMAT_PARAM);
    if (isHelp || CommonUtils.isEmptyTrimmed(format)) {
      format = "help";
    }
    
    String beanLocation[] = getBeanLocation(request);
    
    for(String bloc : beanLocation){
    	if(!validate(bloc)){
        	sendError(response, HttpServletResponse.SC_BAD_REQUEST, "Invalid Request URL");
        }
    }
    
    try {
      response.setHeader("Cache-Control", "no-cache");
      BeanController bc = new BeanController(beanLocation[0], beanLocation[1]);
      bc.setRequestedFields(request.getParameterValues("field"));
      parameters.remove("field");
      if (parameters.size() > 0) {
        if (!checkAuthorized(request, response, true))
          return;
        bc.process(parameters);
      }
      else {
        bc.setFormat(format);
        response.setContentType(bc.getContentType());
        bc.write(response.getWriter());
      }
    }
    catch (Throwable t) {
      sendException(response, "failed for " + beanLocation[1], t);
    }
  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (!checkAuthorized(request, response, true))
      return;
    // Reading post content must happen early
    String content = CommonUtils.getStreamAsString(request.getInputStream(), "\n");
    Map parameters = getParameterMap(request);
    String format = getParameter(parameters, AbstractResourceFormatter.BEAN_FORMAT_PARAM);
    String form[] = parameters.remove("form");
    String actions[] = parameters.remove("action");
    String properties[] = parameters.remove("property");
    if (format == null) {
      format = "spring";
    }
    if (form != null) {
      content = URLDecoder.decode(content, "UTF-8");
      if (form.length != 1 && CommonUtils.isEmptyTrimmed(form[0]) || properties != null) {
        sendError(response, HttpServletResponse.SC_BAD_REQUEST, "Cannot specify both form and property");
        return;
      }
      int p = content.indexOf("=");
      properties = new String[] { content.substring(0, p) };
      content = content.substring(p + 1);
    }
    if (actions != null && properties != null) {
      sendError(response, HttpServletResponse.SC_BAD_REQUEST, "Cannot specify both action and property");
      return;
    }
    if (properties != null && CommonUtils.isEmptyTrimmed(content)) {
      sendError(response, HttpServletResponse.SC_BAD_REQUEST, "Must send content to set property");
      return;
    }

    if (actions != null)
      for (String action : actions)
        parameters.put(action, null);

    if (properties != null)
      for (String property : properties)
        parameters.put(property, new String[] { format, content });
    
    if(!validate(request.getPathInfo()) || !validate(request.getRequestURL().toString())){
    	sendError(response, HttpServletResponse.SC_BAD_REQUEST, "Invalid Request URL");
    }

    String beanLocation[] = getBeanLocation(request);
    
    for(String bloc : beanLocation){
    	if(!validate(bloc)){
        	sendError(response, HttpServletResponse.SC_BAD_REQUEST, "Invalid Request URL");
        }
    }
    try {
      response.setHeader("Cache-Control", "no-cache");
      BeanController bc = new BeanController(beanLocation[0], beanLocation[1]);
      bc.process(parameters);
      response.setContentType(bc.getContentType());
    }
    catch (Throwable t) {
      sendException(response, "POST failed", t);
    }
  }

  private boolean checkAuthorized(HttpServletRequest request, HttpServletResponse response, boolean forWrite) {
    ManagementNetworkSecurity mns = ManagementNetworkSecurity.getInstance();
    boolean authorized = mns == null;
    try {
      if (!authorized)
        authorized = mns.isAuthorized(InetAddress.getByName(request.getRemoteAddr()), forWrite);
    }
    catch (UnknownHostException e) {
    }
    if (!authorized)
      sendError(response, HttpServletResponse.SC_UNAUTHORIZED, request.getRemoteAddr() + " access not allowed");
    return authorized;
  }

  private String[] getBeanLocation(HttpServletRequest request) {
    String result[] = new String[2];
    String	base = request.getPathInfo();
    result[1] = base == null ? "" : base.substring(1);
    int suffixToCut = result[1].length();
    String url = request.getRequestURL().toString();
    result[0] = url.substring(0, url.length() - suffixToCut);
    return result;
  }
  
  private boolean validate(String reqUrl){
	  if(validator != null)
		  return validator.validate(reqUrl);
	  else
		  return true;
  }

  private String getParameter(Map map, String key) {
    String values[] = map.remove(key);
    return values == null || values.length == 0 ? null : values[0];
  }

  @SuppressWarnings("unchecked")
  private Map getParameterMap(HttpServletRequest request) {
    return new HashMap(request.getParameterMap());
  }

  private void sendError(HttpServletResponse response, int statusCode, String message) {
    try {
      response.sendError(statusCode, message);
    }
    catch (Throwable t) {
      throw CommonUtils.runtimeException(t);
    }
  }

  private void sendException(HttpServletResponse response, String message, Throwable cause) {
    String errorText = message + ": " + cause + ".  " + CommonUtils.redirectPrintStackTraceToString(cause);
    if (cause instanceof IOException)
      LOGGER.warn("IOException: " + errorText);
    else if (cause instanceof IllegalArgumentException) {
      LOGGER.warn("Bad client request: " + errorText);
      sendError(response, HttpServletResponse.SC_BAD_REQUEST, errorText);
    }
    else {
      LOGGER.error("INTERNAL SERVER ERROR: " + errorText);
      sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorText);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy