You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

App.java 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * SonarQube, open source software quality management tool.
  3. * Copyright (C) 2008-2014 SonarSource
  4. * mailto:contact AT sonarsource DOT com
  5. *
  6. * SonarQube is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * SonarQube is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.application;
  21. import org.apache.commons.io.FilenameUtils;
  22. import org.apache.commons.lang.StringUtils;
  23. import org.slf4j.Logger;
  24. import org.slf4j.LoggerFactory;
  25. import org.sonar.process.JmxUtils;
  26. import org.sonar.process.MinimumViableSystem;
  27. import org.sonar.process.Monitor;
  28. import org.sonar.process.MonitoredProcess;
  29. import org.sonar.process.ProcessLogging;
  30. import org.sonar.process.ProcessMXBean;
  31. import org.sonar.process.ProcessUtils;
  32. import org.sonar.process.ProcessWrapper;
  33. import org.sonar.process.Props;
  34. import org.sonar.search.SearchServer;
  35. import java.io.File;
  36. import java.io.IOException;
  37. import java.net.URISyntaxException;
  38. import java.util.Properties;
  39. /**
  40. * Entry-point of process that starts and monitors elasticsearch and web servers
  41. */
  42. public class App implements ProcessMXBean {
  43. private Monitor monitor = new Monitor();
  44. private ProcessWrapper elasticsearch;
  45. private ProcessWrapper server;
  46. private boolean success = false;
  47. public App() {
  48. JmxUtils.registerMBean(this, "SonarQube");
  49. ProcessUtils.addSelfShutdownHook(this);
  50. }
  51. public void start(Props props) throws InterruptedException {
  52. try {
  53. Logger logger = LoggerFactory.getLogger(getClass());
  54. if (props.containsValue(MonitoredProcess.DEBUG_AGENT)) {
  55. logger.info("**********************************************************");
  56. logger.info("* sonarQube is running in debug mode. No monitoring *");
  57. logger.info("**********************************************************");
  58. }
  59. monitor.start();
  60. File homeDir = props.fileOf("sonar.path.home");
  61. File tempDir = props.fileOf("sonar.path.temp");
  62. elasticsearch = new ProcessWrapper(JmxUtils.SEARCH_SERVER_NAME);
  63. elasticsearch
  64. .setWorkDir(homeDir)
  65. .setJmxPort(props.intOf(DefaultSettings.SEARCH_JMX_PORT))
  66. .addJavaOpts(props.of(DefaultSettings.SEARCH_JAVA_OPTS))
  67. .setTempDirectory(tempDir.getAbsoluteFile())
  68. .setClassName("org.sonar.search.SearchServer")
  69. .addProperties(props.rawProperties())
  70. .addClasspath("./lib/common/*")
  71. .addClasspath("./lib/search/*");
  72. if (elasticsearch.execute()) {
  73. monitor.registerProcess(elasticsearch);
  74. if (elasticsearch.waitForReady()) {
  75. logger.info("search server is up");
  76. // do not yet start SQ in cluster mode. See SONAR-5483 & SONAR-5391
  77. if (StringUtils.isEmpty(props.of(DefaultSettings.CLUSTER_MASTER, null))) {
  78. server = new ProcessWrapper(JmxUtils.WEB_SERVER_NAME)
  79. .setWorkDir(homeDir)
  80. .setJmxPort(props.intOf(DefaultSettings.WEB_JMX_PORT))
  81. .addJavaOpts(props.of(DefaultSettings.WEB_JAVA_OPTS))
  82. .setTempDirectory(tempDir.getAbsoluteFile())
  83. // required for logback tomcat valve
  84. .setLogDir(props.fileOf("sonar.path.logs"))
  85. .setClassName("org.sonar.server.app.WebServer")
  86. .addProperties(props.rawProperties())
  87. .addClasspath("./lib/common/*")
  88. .addClasspath("./lib/server/*");
  89. String driverPath = props.of(JdbcSettings.PROPERTY_DRIVER_PATH);
  90. if (driverPath != null) {
  91. server.addClasspath(driverPath);
  92. }
  93. if (server.execute()) {
  94. monitor.registerProcess(server);
  95. if (server.waitForReady()) {
  96. success = true;
  97. logger.info("web server is up");
  98. monitor.join();
  99. }
  100. }
  101. } else {
  102. success = true;
  103. monitor.join();
  104. }
  105. }
  106. }
  107. } finally {
  108. terminate();
  109. }
  110. }
  111. static String starPath(File homeDir, String relativePath) {
  112. File dir = new File(homeDir, relativePath);
  113. return FilenameUtils.concat(dir.getAbsolutePath(), "*");
  114. }
  115. @Override
  116. public boolean isReady() {
  117. return monitor.isAlive();
  118. }
  119. @Override
  120. public long ping() {
  121. return System.currentTimeMillis();
  122. }
  123. @Override
  124. public void terminate() {
  125. if (monitor != null && monitor.isAlive()) {
  126. monitor.terminate();
  127. monitor.interrupt();
  128. monitor = null;
  129. }
  130. if (server != null) {
  131. server.terminate();
  132. server = null;
  133. }
  134. if (elasticsearch != null) {
  135. elasticsearch.terminate();
  136. elasticsearch = null;
  137. }
  138. }
  139. private boolean isSuccess() {
  140. return success;
  141. }
  142. public static void main(String[] args) {
  143. new MinimumViableSystem().check();
  144. CommandLineParser cli = new CommandLineParser();
  145. Properties rawProperties = cli.parseArguments(args);
  146. Props props = null;
  147. try {
  148. props = new PropsBuilder(rawProperties, new JdbcSettings()).build();
  149. new ProcessLogging().configure(props, "/org/sonar/application/logback.xml");
  150. } catch (IOException e) {
  151. throw new IllegalStateException(e.getMessage());
  152. } catch (URISyntaxException e) {
  153. throw new IllegalStateException(e.getMessage());
  154. }
  155. App app = new App();
  156. try {
  157. // start and wait for shutdown command
  158. if (props.contains(SearchServer.ES_CLUSTER_INET)) {
  159. LoggerFactory.getLogger(App.class).info("SonarQube slave configured to join SonarQube master : {}", props.of(SearchServer.ES_CLUSTER_INET));
  160. }
  161. app.start(props);
  162. } catch (InterruptedException e) {
  163. LoggerFactory.getLogger(App.class).info("interrupted");
  164. } finally {
  165. LoggerFactory.getLogger(App.class).info("stopped");
  166. System.exit(app.isSuccess() ? 0 : 1);
  167. }
  168. }
  169. }