org.apache.lens.server.LensServer.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.lens.server.LensServer.java

Source

/**
 * 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.lens.server;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

import javax.ws.rs.core.UriBuilder;

import org.apache.lens.server.api.LensConfConstants;
import org.apache.lens.server.api.metrics.MetricsService;
import org.apache.lens.server.metrics.MetricsServiceImpl;
import org.apache.lens.server.ui.UIApp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hive.conf.HiveConf;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.servlet.ServletRegistration;
import org.glassfish.grizzly.servlet.WebappContext;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.slf4j.bridge.SLF4JBridgeHandler;

import com.codahale.metrics.servlets.AdminServlet;
import lombok.Getter;

/**
 * The Class LensServer.
 */
public class LensServer {

    /** The Constant LOG. */
    public static final Log LOG = LogFactory.getLog(LensServer.class);

    private static final String SEP_LINE = "\n###############################################################\n";

    @Getter
    private final List<HttpServer> serverList = new ArrayList<HttpServer>();

    /** The conf. */
    final HiveConf conf;

    /**
     * This flag indicates that the lens server can run, When this is set to false, main thread bails out.
     */
    volatile boolean canRun = true;

    static {
        SLF4JBridgeHandler.removeHandlersForRootLogger();
        SLF4JBridgeHandler.install();
    }

    static LensServer createLensServer(HiveConf conf) throws IOException {
        final LensServer thisServer = new LensServer(conf);
        return thisServer;
    }

    /**
     * Instantiates a new lens server.
     *
     * @param conf the conf
     * @throws IOException Signals that an I/O exception has occurred.
     */
    private LensServer(HiveConf conf) throws IOException {
        this.conf = conf;
        startServices(conf);
        String baseURI = conf.get(LensConfConstants.SERVER_BASE_URL, LensConfConstants.DEFAULT_SERVER_BASE_URL);
        HttpServer server = GrizzlyHttpServerFactory.createHttpServer(UriBuilder.fromUri(baseURI).build(), getApp(),
                false);
        serverList.add(server);

        WebappContext adminCtx = new WebappContext("admin", "");
        adminCtx.setAttribute("com.codahale.metrics.servlets.MetricsServlet.registry",
                ((MetricsServiceImpl) LensServices.get().getService(MetricsService.NAME)).getMetricRegistry());
        adminCtx.setAttribute("com.codahale.metrics.servlets.HealthCheckServlet.registry",
                ((MetricsServiceImpl) LensServices.get().getService(MetricsService.NAME)).getHealthCheck());

        final ServletRegistration sgMetrics = adminCtx.addServlet("admin", new AdminServlet());
        sgMetrics.addMapping("/admin/*");

        adminCtx.deploy(server);

        if (conf.getBoolean(LensConfConstants.SERVER_UI_ENABLE, LensConfConstants.DEFAULT_SERVER_UI_ENABLE)) {
            String uiServerURI = conf.get(LensConfConstants.SERVER_UI_URI, LensConfConstants.DEFAULT_SERVER_UI_URI);
            HttpServer uiServer = GrizzlyHttpServerFactory.createHttpServer(UriBuilder.fromUri(uiServerURI).build(),
                    getUIApp(), false);
            serverList.add(uiServer);
        }
    }

    private ResourceConfig getApp() {
        ResourceConfig app = ResourceConfig.forApplicationClass(LensApplication.class);
        app.register(new LoggingFilter(Logger.getLogger(LensServer.class.getName() + ".request"), true));
        app.setApplicationName("AllApps");
        return app;
    }

    private ResourceConfig getUIApp() {
        ResourceConfig uiApp = ResourceConfig.forApplicationClass(UIApp.class);
        uiApp.register(new LoggingFilter(Logger.getLogger(LensServer.class.getName() + ".ui_request"), true));
        uiApp.setApplicationName("Lens UI");
        return uiApp;
    }

    /**
     * Start services.
     *
     * @param conf the conf
     */
    public void startServices(HiveConf conf) {
        LensServices.get().init(conf);
        LensServices.get().start();
    }

    /**
     * Start.
     *
     * @throws IOException Signals that an I/O exception has occurred.
     */
    public synchronized void start() throws IOException {
        for (HttpServer server : serverList) {
            server.start();
        }
    }

    /**
     * Stop.
     */
    public synchronized void stop() {
        for (HttpServer server : serverList) {
            server.shutdown();
        }
        LensServices.get().stop();
        printShutdownMessage();
    }

    /**
     * This keeps the server running till a shutdown is triggered. Either through a shutdown sequence initiated by an
     * administrator or if applications encounters a fatal exception or it enters an unrecoverable state.
     */
    private void join() {
        while (canRun) {
            synchronized (this) {
                try {
                    wait(2000);
                } catch (InterruptedException e) {
                    LOG.warn("Received an interrupt in the main loop", e);
                }
            }
        }
        LOG.info("Exiting main run loop...");
    }

    /**
     * The main method.
     *
     * @param args the arguments
     * @throws Exception the exception
     */
    public static void main(String[] args) throws Exception {

        printStartupMessage();
        try {
            final LensServer thisServer = LensServer.createLensServer(LensServerConf.get());

            registerShutdownHook(thisServer);
            registerDefaultExceptionHandler();

            thisServer.start();
            thisServer.join();
        } catch (Exception exc) {
            LOG.fatal("Error while creating Lens server", exc);
            try {
                LensServices.get().stop();
            } catch (Exception e) {
                LOG.error("Error stopping services", e);
            }
        }
    }

    /**
     * Print message from lens-build-info file during startup.
     */
    private static void printStartupMessage() {
        StringBuilder buffer = new StringBuilder();
        buffer.append(SEP_LINE);
        buffer.append("                    Lens Server (STARTUP)");
        Properties buildProperties = new Properties();
        InputStream buildPropertiesResource = LensServer.class.getResourceAsStream("/lens-build-info.properties");
        if (buildPropertiesResource != null) {
            try {
                buildProperties.load(buildPropertiesResource);
                for (Map.Entry entry : buildProperties.entrySet()) {
                    buffer.append('\n').append('\t').append(entry.getKey()).append(":\t").append(entry.getValue());
                }
            } catch (Throwable e) {
                buffer.append("*** Unable to get build info ***");
            }
        } else {
            buffer.append("*** Unable to get build info ***");
        }
        buffer.append(SEP_LINE);
        LOG.info(buffer.toString());
    }

    /**
     * Print message before the lens server stops.
     */
    private static void printShutdownMessage() {
        StringBuilder buffer = new StringBuilder();
        buffer.append(SEP_LINE);
        buffer.append("                    Lens Server (SHUTDOWN)");
        buffer.append(SEP_LINE);
        LOG.info(buffer.toString());
    }

    /**
     * Registering a shutdown hook to listen to SIGTERM events. Upon receiving a SIGTERM, notify the server, which is put
     * on wait state.
     */
    private static void registerShutdownHook(final LensServer thisServer) {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                Thread.currentThread().setName("Shutdown");
                LOG.info("Server has been requested to be stopped.");
                thisServer.canRun = false;
                thisServer.stop();
            }
        });
    }

    /** Registering a default uncaught exception handler. */
    private static void registerDefaultExceptionHandler() {
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                LOG.fatal("Uncaught exception in Thread " + t, e);
            }
        });
    }
}