001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package org.apache.hadoop.hbase.rest;
020
021import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
022import org.apache.commons.lang3.ArrayUtils;
023import org.apache.hadoop.conf.Configuration;
024import org.apache.hadoop.hbase.security.UserProvider;
025import org.apache.hadoop.hbase.http.HttpServerUtil;
026import org.apache.hadoop.util.StringUtils;
027
028import org.eclipse.jetty.server.HttpConfiguration;
029import org.eclipse.jetty.server.HttpConnectionFactory;
030import org.eclipse.jetty.server.Server;
031import org.eclipse.jetty.servlet.ServletContextHandler;
032import org.eclipse.jetty.server.ServerConnector;
033import org.eclipse.jetty.servlet.ServletHolder;
034
035import org.glassfish.jersey.server.ResourceConfig;
036import org.glassfish.jersey.servlet.ServletContainer;
037import org.slf4j.Logger;
038import org.slf4j.LoggerFactory;
039
040import javax.servlet.DispatcherType;
041import java.util.Arrays;
042import java.util.EnumSet;
043
044public class HBaseRESTTestingUtility {
045
046  private static final Logger LOG = LoggerFactory.getLogger(HBaseRESTTestingUtility.class);
047
048  private int testServletPort;
049  private Server server;
050
051  public int getServletPort() {
052    return testServletPort;
053  }
054
055  public void startServletContainer(Configuration conf) throws Exception {
056    if (server != null) {
057      LOG.error("ServletContainer already running");
058      return;
059    }
060
061    // Inject the conf for the test by being first to make singleton
062    RESTServlet.getInstance(conf, UserProvider.instantiate(conf));
063
064    // set up the Jersey servlet container for Jetty
065    ResourceConfig app = new ResourceConfig().
066        packages("org.apache.hadoop.hbase.rest").register(JacksonJaxbJsonProvider.class);
067    ServletHolder sh = new ServletHolder(new ServletContainer(app));
068
069    // set up Jetty and run the embedded server
070    server = new Server(0);
071    LOG.info("configured " + ServletContainer.class.getName());
072
073    HttpConfiguration httpConfig = new HttpConfiguration();
074    httpConfig.setSendDateHeader(false);
075    httpConfig.setSendServerVersion(false);
076    ServerConnector serverConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
077    serverConnector.setPort(testServletPort);
078
079    server.addConnector(serverConnector);
080
081    // set up context
082    ServletContextHandler ctxHandler = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
083    ctxHandler.addServlet(sh, "/*");
084    // Load filters specified from configuration.
085    String[] filterClasses = conf.getStrings(Constants.FILTER_CLASSES,
086        ArrayUtils.EMPTY_STRING_ARRAY);
087    for (String filter : filterClasses) {
088      filter = filter.trim();
089      ctxHandler.addFilter(filter, "/*", EnumSet.of(DispatcherType.REQUEST));
090    }
091    LOG.info("Loaded filter classes :" + Arrays.toString(filterClasses));
092
093    conf.set(RESTServer.REST_CSRF_BROWSER_USERAGENTS_REGEX_KEY, ".*");
094    RESTServer.addCSRFFilter(ctxHandler, conf);
095
096    HttpServerUtil.constrainHttpMethods(ctxHandler, false);
097
098    // start the server
099    server.start();
100    // get the port
101    testServletPort = ((ServerConnector)server.getConnectors()[0]).getLocalPort();
102
103    LOG.info("started " + server.getClass().getName() + " on port " +
104      testServletPort);
105  }
106
107  public void shutdownServletContainer() {
108    if (server != null) try {
109      server.stop();
110      server = null;
111      RESTServlet.stop();
112    } catch (Exception e) {
113      LOG.warn(StringUtils.stringifyException(e));
114    }
115  }
116}