diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-09-12 10:24:07 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-09-12 10:24:07 +0200 |
commit | 1fd2e682bfe5b6732e9097d0d3e57495da9e058c (patch) | |
tree | 765cfa78c98b9ae09828104cddcad0b1d5c2c253 /server/sonar-server/src | |
parent | 85da787c6f0f5c47ec6e19681ed00fa8661f0fb8 (diff) | |
parent | aeee283d2109c425828c96bc2952b947cce56566 (diff) | |
download | sonarqube-1fd2e682bfe5b6732e9097d0d3e57495da9e058c.tar.gz sonarqube-1fd2e682bfe5b6732e9097d0d3e57495da9e058c.zip |
Merge branch 'process-monitoring' into branch-4.5
Diffstat (limited to 'server/sonar-server/src')
8 files changed, 89 insertions, 85 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java b/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java index 2356ff340e8..a7146eda913 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java @@ -19,22 +19,32 @@ */ package org.sonar.server.app; +import com.google.common.base.Throwables; +import com.google.common.util.concurrent.Uninterruptibles; +import org.apache.catalina.Container; +import org.apache.catalina.Executor; +import org.apache.catalina.Lifecycle; +import org.apache.catalina.LifecycleEvent; +import org.apache.catalina.LifecycleListener; +import org.apache.catalina.LifecycleState; +import org.apache.catalina.Server; +import org.apache.catalina.Service; +import org.apache.catalina.connector.Connector; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; import org.apache.commons.io.FileUtils; import org.slf4j.LoggerFactory; -import org.sonar.process.ProcessUtils; import org.sonar.process.Props; -import org.sonar.process.Terminable; import java.io.File; +import java.util.concurrent.TimeUnit; -class EmbeddedTomcat implements Terminable { +class EmbeddedTomcat { private final Props props; private Tomcat tomcat = null; private Thread hook = null; - private boolean ready = false; + private volatile StandardContext webappContext; EmbeddedTomcat(Props props) { this.props = props; @@ -62,45 +72,52 @@ class EmbeddedTomcat implements Terminable { tomcat.getHost().setDeployOnStartup(true); Logging.configure(tomcat, props); Connectors.configure(tomcat, props); - StandardContext webappContext = Webapp.configure(tomcat, props); - ProcessUtils.addSelfShutdownHook(this); + webappContext = Webapp.configure(tomcat, props); tomcat.start(); + waitForWebappReady(); - if (webappContext.getState().isAvailable()) { - ready = true; - tomcat.getServer().await(); - } } catch (Exception e) { - throw new IllegalStateException("Fail to start web server", e); - } finally { - // Failed to start or received a shutdown command (should never occur as shutdown port is disabled) - terminate(); + Throwables.propagate(e); } } - private File tomcatBasedir() { - return new File(props.value("sonar.path.temp"), "tc"); + private void waitForWebappReady() { + while (true) { + switch (webappContext.getState()) { + case NEW: + case INITIALIZING: + case INITIALIZED: + case STARTING_PREP: + case STARTING: + Uninterruptibles.sleepUninterruptibly(300L, TimeUnit.MILLISECONDS); + break; + case STARTED: + // ok + return; + default: + // problem, stopped or failed + throw new IllegalStateException("YYY Webapp did not start"); + } + } } - boolean isReady() { - return ready && tomcat != null; + private File tomcatBasedir() { + return new File(props.value("sonar.path.temp"), "tc"); } - @Override - public void terminate() { - if (tomcat != null) { - synchronized (tomcat) { - if (tomcat.getServer().getState().isAvailable()) { - try { - tomcat.stop(); - tomcat.destroy(); - } catch (Exception e) { - LoggerFactory.getLogger(EmbeddedTomcat.class).error("Fail to stop web service", e); - } - } + void terminate() { + if (tomcat.getServer().getState().isAvailable()) { + try { + tomcat.stop(); + tomcat.destroy(); + } catch (Exception e) { + LoggerFactory.getLogger(EmbeddedTomcat.class).error("Fail to stop web server", e); } } - ready = false; FileUtils.deleteQuietly(tomcatBasedir()); } + + void awaitTermination() { + tomcat.getServer().await(); + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java b/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java index d5bc4fde7de..94bc1214f0f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java @@ -19,18 +19,16 @@ */ package org.sonar.server.app; -import org.slf4j.LoggerFactory; -import org.sonar.process.ConfigurationUtils; import org.sonar.process.MinimumViableSystem; import org.sonar.process.MonitoredProcess; +import org.sonar.process.ProcessEntryPoint; import org.sonar.process.Props; -public class WebServer extends MonitoredProcess { +public class WebServer implements MonitoredProcess { private final EmbeddedTomcat tomcat; WebServer(Props props) throws Exception { - super(props); new MinimumViableSystem() .setRequiredJavaOption("file.encoding", "UTF-8") .check(); @@ -38,32 +36,27 @@ public class WebServer extends MonitoredProcess { } @Override - protected void doStart() { - try { - tomcat.start(); - } catch (Exception e) { - LoggerFactory.getLogger(getClass()).error("TC error", e); - } finally { - terminate(); - } + public void start() { + tomcat.start(); } @Override - protected void doTerminate() { + public void terminate() { tomcat.terminate(); } @Override - protected boolean doIsReady() { - return tomcat.isReady(); + public void awaitTermination() { + tomcat.awaitTermination(); } /** * Can't be started as is. Needs to be bootstrapped by sonar-application */ public static void main(String[] args) throws Exception { - Props props = ConfigurationUtils.loadPropsFromCommandLineArgs(args); - Logging.init(props); - new WebServer(props).start(); + ProcessEntryPoint entryPoint = ProcessEntryPoint.createForArguments(args); + Logging.init(entryPoint.getProps()); + WebServer server = new WebServer(entryPoint.getProps()); + entryPoint.launch(server); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java b/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java index f959faed106..8445efb22be 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java @@ -64,7 +64,6 @@ class Webapp { String key = entry.getKey().toString(); context.addParameter(key, entry.getValue().toString()); } - return context; } catch (Exception e) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java b/server/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java index 46bc0426333..33efbcd7e06 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java @@ -19,7 +19,7 @@ */ package org.sonar.server.platform; -import org.slf4j.LoggerFactory; +import com.google.common.base.Throwables; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; @@ -46,9 +46,9 @@ public final class PlatformServletContextListener implements ServletContextListe // - server does not stop if webapp fails at startup // - the second listener for jruby on rails is started even if this listener fails. It generates // unexpected errors - LoggerFactory.getLogger(getClass()).error("Fail to start server", t); + // LoggerFactory.getLogger(getClass()).error("Fail to start server", t); stopQuietly(); - throw new IllegalStateException("Fail to start webapp", t); + throw Throwables.propagate(t); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginJarsInstaller.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginJarsInstaller.java index 3884439e166..5abc8a0eaef 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginJarsInstaller.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginJarsInstaller.java @@ -211,9 +211,11 @@ public class ServerPluginJarsInstaller { private void deploy(DefaultPluginMetadata plugin) { LOG.info("Deploy plugin {}", Joiner.on(" / ").skipNulls().join(plugin.getName(), plugin.getVersion(), plugin.getImplementationBuild())); - Preconditions.checkState(plugin.isCompatibleWith(server.getVersion()), - "Plugin %s needs a more recent version of SonarQube than %s. At least %s is expected", - plugin.getKey(), server.getVersion(), plugin.getSonarVersion()); + if (!plugin.isCompatibleWith(server.getVersion())) { + throw MessageException.of(String.format( + "Plugin %s needs a more recent version of SonarQube than %s. At least %s is expected", + plugin.getKey(), server.getVersion(), plugin.getSonarVersion())); + } try { File pluginDeployDir = new File(fs.getDeployedPluginsDir(), plugin.getKey()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java index be40c087f88..90cce6fb4ed 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java @@ -85,7 +85,7 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(1); assertThat(new File(pluginsDir, "foo-plugin-1.0.jar")).exists().isFile(); PluginMetadata plugin = jarsInstaller.getMetadata("foo"); assertThat(plugin.getName()).isEqualTo("Foo"); @@ -101,7 +101,7 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).isEmpty(); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).isEmpty(); } @Test @@ -115,7 +115,7 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); // do not copy foo 1.0 - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(2); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(2); assertThat(new File(pluginsDir, "foo-plugin-2.0.jar")).exists().isFile(); assertThat(new File(pluginsDir, "bar-plugin-1.0.jar")).exists().isFile(); PluginMetadata plugin = jarsInstaller.getMetadata("foo"); @@ -138,7 +138,7 @@ public class ServerPluginJarsInstallerTest { assertThat(plugin.isUseChildFirstClassLoader()).isFalse(); // check that the file is still present in extensions/plugins - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(1); assertThat(new File(pluginsDir, "foo-plugin-1.0.jar")).exists().isFile(); } @@ -151,13 +151,13 @@ public class ServerPluginJarsInstallerTest { // nothing to install but keep the file assertThat(jarsInstaller.getMetadata()).isEmpty(); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(1); assertThat(new File(pluginsDir, "not-a-plugin.jar")).exists().isFile(); } @Test public void fail_if_plugin_requires_greater_SQ_version() throws Exception { - exception.expect(IllegalStateException.class); + exception.expect(MessageException.class); exception.expectMessage("Plugin switchoffviolations needs a more recent version of SonarQube than 2.0. At least 2.5 is expected"); when(upgradeStatus.isFreshInstall()).thenReturn(false); @@ -174,8 +174,8 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(1); - assertThat(FileUtils.listFiles(downloadsDir, new String[]{"jar"}, false)).isEmpty(); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(downloadsDir, new String[] {"jar"}, false)).isEmpty(); assertThat(new File(pluginsDir, "foo-plugin-1.0.jar")).exists().isFile(); } @@ -187,8 +187,8 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(1); - assertThat(FileUtils.listFiles(downloadsDir, new String[]{"jar"}, false)).isEmpty(); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(downloadsDir, new String[] {"jar"}, false)).isEmpty(); assertThat(new File(pluginsDir, "foo-plugin-2.0.jar")).exists().isFile(); } @@ -205,8 +205,8 @@ public class ServerPluginJarsInstallerTest { PluginMetadata plugin = jarsInstaller.getMetadata("foo"); assertThat(plugin).isNotNull(); assertThat(plugin.getVersion()).isEqualTo("2.0"); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(1); - assertThat(FileUtils.listFiles(downloadsDir, new String[]{"jar"}, false)).isEmpty(); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(downloadsDir, new String[] {"jar"}, false)).isEmpty(); File installed = new File(pluginsDir, "foo-plugin-1.0.jar"); assertThat(installed).exists().isFile(); } @@ -218,7 +218,7 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).isEmpty(); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).isEmpty(); assertThat(trashDir).doesNotExist(); } @@ -247,8 +247,8 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); jarsInstaller.uninstall("foo"); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).isEmpty(); - assertThat(FileUtils.listFiles(trashDir, new String[]{"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).isEmpty(); + assertThat(FileUtils.listFiles(trashDir, new String[] {"jar"}, false)).hasSize(1); assertThat(jarsInstaller.getUninstalls()).containsOnly("foo-plugin-1.0.jar"); } @@ -261,8 +261,8 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.uninstall("foo"); jarsInstaller.cancelUninstalls(); - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(1); - assertThat(FileUtils.listFiles(trashDir, new String[]{"jar"}, false)).hasSize(0); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(trashDir, new String[] {"jar"}, false)).hasSize(0); assertThat(jarsInstaller.getUninstalls()).isEmpty(); } @@ -274,10 +274,10 @@ public class ServerPluginJarsInstallerTest { jarsInstaller.install(); // do not deploy in extensions/plugins - assertThat(FileUtils.listFiles(pluginsDir, new String[]{"jar"}, false)).hasSize(0); + assertThat(FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false)).hasSize(0); // do not remove from lib/core-plugins - assertThat(FileUtils.listFiles(coreDir, new String[]{"jar"}, false)).hasSize(1); + assertThat(FileUtils.listFiles(coreDir, new String[] {"jar"}, false)).hasSize(1); PluginMetadata plugin = jarsInstaller.getMetadata("foo"); assertThat(plugin).isNotNull(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/search/BaseIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/search/BaseIndexTest.java index e92fd5b936f..8270a46f06e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/search/BaseIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/search/BaseIndexTest.java @@ -61,10 +61,9 @@ public class BaseIndexTest { Properties properties = new Properties(); properties.setProperty(IndexProperties.CLUSTER_NAME, clusterName); properties.setProperty(IndexProperties.NODE_PORT, clusterPort.toString()); - properties.setProperty(MonitoredProcess.NAME_PROPERTY, "ES"); properties.setProperty(SearchServer.SONAR_PATH_HOME, temp.getRoot().getAbsolutePath()); try { - searchServer = new SearchServer(new Props(properties), false, false); + searchServer = new SearchServer(new Props(properties)); } catch (Exception e) { e.printStackTrace(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java b/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java index ce6fad22f77..1a935cb2394 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java +++ b/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java @@ -26,7 +26,6 @@ import org.apache.commons.lang.StringUtils; import org.junit.rules.ExternalResource; import org.sonar.api.database.DatabaseProperties; import org.sonar.api.resources.Language; -import org.sonar.process.MonitoredProcess; import org.sonar.process.NetworkUtils; import org.sonar.process.Props; import org.sonar.search.SearchServer; @@ -35,6 +34,7 @@ import org.sonar.server.search.IndexProperties; import org.sonar.server.ws.WsTester; import javax.annotation.Nullable; + import java.io.File; import java.util.Arrays; import java.util.List; @@ -71,13 +71,8 @@ public class ServerTester extends ExternalResource { Properties properties = new Properties(); properties.setProperty(IndexProperties.CLUSTER_NAME, clusterName); properties.setProperty(IndexProperties.NODE_PORT, clusterPort.toString()); - properties.setProperty(MonitoredProcess.NAME_PROPERTY, "ES"); properties.setProperty(SearchServer.SONAR_PATH_HOME, homeDir.getAbsolutePath()); - try { - searchServer = new SearchServer(new Props(properties), false, false); - } catch (Exception e) { - e.printStackTrace(); - } + searchServer = new SearchServer(new Props(properties)); } /** @@ -99,7 +94,6 @@ public class ServerTester extends ExternalResource { properties.setProperty(IndexProperties.CLUSTER_NAME, clusterName); properties.setProperty(IndexProperties.NODE_PORT, clusterPort.toString()); - properties.setProperty(MonitoredProcess.NAME_PROPERTY, "ES"); properties.setProperty("sonar.path.home", homeDir.getAbsolutePath()); properties.setProperty(DatabaseProperties.PROP_URL, "jdbc:h2:" + homeDir.getAbsolutePath() + "/h2"); |