PageRenderTime 266ms CodeModel.GetById 121ms app.highlight 47ms RepoModel.GetById 34ms app.codeStats 0ms

/server/src/main/java/org/apache/oozie/server/EmbeddedOozieServer.java

https://github.com/apache/oozie
Java | 290 lines | 215 code | 30 blank | 45 comment | 20 complexity | 3d5d562085086a049c1971407fea2e38 MD5 | raw file
  1/**
  2 * Licensed to the Apache Software Foundation (ASF) under one
  3 * or more contributor license agreements.  See the NOTICE file
  4 * distributed with this work for additional information
  5 * regarding copyright ownership.  The ASF licenses this file
  6 * to you under the Apache License, Version 2.0 (the
  7 * "License"); you may not use this file except in compliance
  8 * with the License.  You may obtain a copy of the License at
  9 *
 10 *      http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing, software
 13 * distributed under the License is distributed on an "AS IS" BASIS,
 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18
 19package org.apache.oozie.server;
 20
 21import com.google.inject.Guice;
 22import com.google.inject.Inject;
 23import com.google.inject.Injector;
 24import com.google.inject.ProvisionException;
 25import org.apache.hadoop.conf.Configuration;
 26import org.apache.oozie.server.guice.OozieGuiceModule;
 27import org.apache.oozie.service.ConfigurationService;
 28import org.apache.oozie.service.ServiceException;
 29import org.apache.oozie.service.Services;
 30import org.apache.oozie.util.ConfigUtils;
 31import org.eclipse.jetty.rewrite.handler.RewriteHandler;
 32import org.eclipse.jetty.security.ConstraintSecurityHandler;
 33import org.eclipse.jetty.server.Connector;
 34import org.eclipse.jetty.server.HttpConfiguration;
 35import org.eclipse.jetty.server.HttpConnectionFactory;
 36import org.eclipse.jetty.server.Server;
 37import org.eclipse.jetty.server.ServerConnector;
 38import org.eclipse.jetty.server.handler.HandlerCollection;
 39import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
 40import org.eclipse.jetty.webapp.WebAppContext;
 41import org.slf4j.Logger;
 42import org.slf4j.LoggerFactory;
 43
 44import javax.servlet.http.HttpServletResponse;
 45import java.io.IOException;
 46import java.net.URISyntaxException;
 47import java.util.Objects;
 48
 49/**
 50 *  Class to start Oozie inside an embedded Jetty server.
 51 */
 52public class EmbeddedOozieServer {
 53    private static final Logger LOG = LoggerFactory.getLogger(EmbeddedOozieServer.class);
 54    protected static final String OOZIE_HTTPS_TRUSTSTORE_FILE = "oozie.https.truststore.file";
 55    protected static final String OOZIE_HTTPS_TRUSTSTORE_PASS = "oozie.https.truststore.pass";
 56    protected static final String TRUSTSTORE_PATH_SYSTEM_PROPERTY = "javax.net.ssl.trustStore";
 57    protected static final String TRUSTSTORE_PASS_SYSTEM_PROPERTY = "javax.net.ssl.trustStorePassword";
 58    private static String contextPath;
 59    protected Server server;
 60    private int httpPort;
 61    private int httpsPort;
 62    private final WebAppContext servletContextHandler;
 63    private final ServletMapper oozieServletMapper;
 64    private final FilterMapper oozieFilterMapper;
 65    private JspHandler jspHandler;
 66    private Services serviceController;
 67    private SSLServerConnectorFactory sslServerConnectorFactory;
 68    private Configuration conf;
 69    private final RewriteHandler oozieRewriteHandler;
 70    private final ConstraintSecurityHandler constraintSecurityHandler;
 71
 72    /**
 73     * Construct Oozie server
 74     * @param server jetty server to be embedded
 75     * @param jspHandler handler responsible for setting webapp context for JSP
 76     * @param serviceController controller for Oozie services; must be already initialized
 77     * @param sslServerConnectorFactory factory to create server connector configured for SSL
 78     * @param oozieRewriteHandler URL rewriter
 79     * @param servletContextHandler main web application context handler
 80     * @param oozieServletMapper maps servlets to URLs
 81     * @param oozieFilterMapper  maps filters
 82     * @param constraintSecurityHandler constraint security handler
 83     */
 84    @Inject
 85    public EmbeddedOozieServer(final Server server,
 86                               final JspHandler jspHandler,
 87                               final Services serviceController,
 88                               final SSLServerConnectorFactory sslServerConnectorFactory,
 89                               final RewriteHandler oozieRewriteHandler,
 90                               final WebAppContext servletContextHandler,
 91                               final ServletMapper oozieServletMapper,
 92                               final FilterMapper oozieFilterMapper,
 93                               final ConstraintSecurityHandler constraintSecurityHandler)
 94    {
 95        this.constraintSecurityHandler = constraintSecurityHandler;
 96        this.serviceController = Objects.requireNonNull(serviceController, "serviceController is null");
 97        this.jspHandler = Objects.requireNonNull(jspHandler, "jspHandler is null");
 98        this.sslServerConnectorFactory = Objects.requireNonNull(sslServerConnectorFactory,
 99                "sslServerConnectorFactory is null");
100        this.server = Objects.requireNonNull(server, "server is null");
101        this.oozieRewriteHandler = Objects.requireNonNull(oozieRewriteHandler, "rewriter is null");
102        this.servletContextHandler = Objects.requireNonNull(servletContextHandler, "servletContextHandler is null");
103        this.oozieServletMapper = Objects.requireNonNull(oozieServletMapper, "oozieServletMapper is null");
104        this.oozieFilterMapper = Objects.requireNonNull(oozieFilterMapper, "oozieFilterMapper is null");
105    }
106
107    /**
108     * Set up the Oozie server by configuring jetty server settings and starts Oozie services
109     *
110     * @throws URISyntaxException if the server URI is not well formatted
111     * @throws IOException in case of IO issues
112     * @throws ServiceException if the server could not start
113     */
114    public void setup() throws URISyntaxException, IOException, ServiceException {
115        conf = serviceController.get(ConfigurationService.class).getConf();
116        setContextPath(conf);
117        httpPort = getConfigPort(ConfigUtils.OOZIE_HTTP_PORT);
118
119        HttpConfiguration httpConfiguration = new HttpConfigurationWrapper(conf).getDefaultHttpConfiguration();
120
121        ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration));
122        connector.setPort(httpPort);
123        connector.setHost(conf.get(ConfigUtils.OOZIE_HTTP_HOSTNAME));
124
125        HandlerCollection handlerCollection = new HandlerCollection();
126        setTrustStore();
127        setTrustStorePassword();
128
129        if (isSecured()) {
130            httpsPort =  getConfigPort(ConfigUtils.OOZIE_HTTPS_PORT);
131            ServerConnector sslConnector = sslServerConnectorFactory.createSecureServerConnector(httpsPort, conf, server);
132            server.setConnectors(new Connector[]{connector, sslConnector});
133            constraintSecurityHandler.setHandler(servletContextHandler);
134            handlerCollection.addHandler(constraintSecurityHandler);
135        }
136        else {
137            server.setConnectors(new Connector[]{connector});
138        }
139
140        servletContextHandler.setContextPath(contextPath);
141        oozieServletMapper.mapOozieServlets();
142        oozieFilterMapper.addFilters();
143
144        servletContextHandler.setParentLoaderPriority(true);
145        jspHandler.setupWebAppContext(servletContextHandler);
146
147        addErrorHandler();
148
149        handlerCollection.addHandler(servletContextHandler);
150        handlerCollection.addHandler(oozieRewriteHandler);
151        server.setHandler(handlerCollection);
152    }
153
154    /**
155     * set the truststore path from the config file, if is not set by the user
156     */
157    private void setTrustStore() {
158        if (System.getProperty(TRUSTSTORE_PATH_SYSTEM_PROPERTY) == null) {
159            final String trustStorePath = conf.get(OOZIE_HTTPS_TRUSTSTORE_FILE);
160            if (trustStorePath != null) {
161                LOG.info("Setting javax.net.ssl.trustStore from config file");
162                System.setProperty(TRUSTSTORE_PATH_SYSTEM_PROPERTY, trustStorePath);
163            }
164        } else {
165            LOG.info("javax.net.ssl.trustStore is already set. The value from config file will be ignored");
166        }
167    }
168
169    /**
170     * set the truststore password from the config file, if is not set by the user
171     */
172    private void setTrustStorePassword() {
173        if (System.getProperty(TRUSTSTORE_PASS_SYSTEM_PROPERTY) == null) {
174            final String trustStorePassword = conf.get(OOZIE_HTTPS_TRUSTSTORE_PASS);
175            if (trustStorePassword != null) {
176                LOG.info("Setting javax.net.ssl.trustStorePassword from config file");
177                System.setProperty(TRUSTSTORE_PASS_SYSTEM_PROPERTY, trustStorePassword);
178            }
179        } else {
180            LOG.info("javax.net.ssl.trustStorePassword is already set. The value from config file will be ignored");
181        }
182    }
183
184    private void addErrorHandler() {
185        ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
186        errorHandler.addErrorPage(HttpServletResponse.SC_BAD_REQUEST, "/error");
187        errorHandler.addErrorPage(HttpServletResponse.SC_UNAUTHORIZED, "/error");
188        errorHandler.addErrorPage(HttpServletResponse.SC_FORBIDDEN, "/error");
189        errorHandler.addErrorPage(HttpServletResponse.SC_NOT_FOUND, "/error");
190        errorHandler.addErrorPage(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "/error");
191        errorHandler.addErrorPage(HttpServletResponse.SC_CONFLICT, "/error");
192        errorHandler.addErrorPage(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "/error");
193        errorHandler.addErrorPage(HttpServletResponse.SC_NOT_IMPLEMENTED, "/error");
194        errorHandler.addErrorPage(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "/error");
195        errorHandler.addErrorPage("java.lang.Throwable", "/error");
196        servletContextHandler.setErrorHandler(errorHandler);
197    }
198
199    private int getConfigPort(String confVar) {
200        String confHttpPort = conf.get(confVar);
201        int port;
202        try {
203            port = Integer.parseInt(confHttpPort);
204        }
205        catch (final NumberFormatException nfe) {
206            throw new NumberFormatException(String.format("Port number for '%s \"%s\" ('%s') is not an integer.",
207                    confVar, confHttpPort, confHttpPort));
208        }
209        return port;
210    }
211
212    private boolean isSecured() {
213        String isSSLEnabled = conf.get("oozie.https.enabled");
214        LOG.info("Server started with oozie.https.enabled = " + isSSLEnabled);
215        return isSSLEnabled != null && Boolean.valueOf(isSSLEnabled);
216    }
217
218    public static void setContextPath(Configuration oozieConfiguration) {
219        String baseUrl = oozieConfiguration.get("oozie.base.url");
220        String contextPath = baseUrl.substring(baseUrl.lastIndexOf("/"));
221        LOG.info("Server started with contextPath = " + contextPath);
222        EmbeddedOozieServer.contextPath = contextPath;
223    }
224
225    public static String getContextPath(Configuration oozieConfiguration) {
226        if (contextPath != null) {
227            return contextPath;
228        }
229
230        setContextPath(oozieConfiguration);
231        return EmbeddedOozieServer.contextPath;
232    }
233
234    public void start() throws Exception {
235        server.start();
236        LOG.info("Server started.");
237    }
238
239    public void shutdown() throws Exception {
240        LOG.info("Shutting down.");
241        if (serviceController != null) {
242            serviceController.destroy();
243            LOG.info("Oozie services stopped.");
244        }
245
246        if (server != null) {
247            server.stop();
248            LOG.info("Server stopped.");
249        }
250    }
251
252    public void join() throws InterruptedException {
253        server.join();
254    }
255
256    public void addShutdownHook() {
257        Runtime.getRuntime().addShutdownHook(new Thread() {
258            public void run() {
259                try {
260                    shutdown();
261                } catch (final Exception e) {
262                    LOG.error(String.format("There were errors during shutdown. Error message: %s", e.getMessage()));
263                }
264            }
265        });
266    }
267
268    public static void main(String[] args) throws Exception {
269        final Injector guiceInjector = Guice.createInjector(new OozieGuiceModule());
270
271        EmbeddedOozieServer embeddedOozieServer = null;
272        try {
273            embeddedOozieServer = guiceInjector.getInstance(EmbeddedOozieServer.class);
274        }
275        catch (final ProvisionException ex) {
276            LOG.error(ex.getMessage());
277            System.exit(1);
278        }
279
280        embeddedOozieServer.addShutdownHook();
281        embeddedOozieServer.setup();
282        try {
283            embeddedOozieServer.start();
284        } catch (final Exception e) {
285            LOG.error(String.format("Could not start EmbeddedOozieServer! Error message: %s", e.getMessage()));
286            System.exit(1);
287        }
288        embeddedOozieServer.join();
289    }
290}