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