diff options
8 files changed, 173 insertions, 27 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/WebDeployContext.java b/server/sonar-server/src/main/java/org/sonar/server/app/WebDeployContext.java new file mode 100644 index 00000000000..688271a79ac --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/app/WebDeployContext.java @@ -0,0 +1,63 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.app; + +import com.google.common.annotations.VisibleForTesting; +import java.io.File; +import java.io.IOException; +import javax.servlet.ServletException; +import org.apache.catalina.startup.Tomcat; +import org.apache.commons.io.FileUtils; +import org.sonar.process.ProcessProperties; +import org.sonar.process.Props; + +import static java.lang.String.format; + +public class WebDeployContext { + + public static final String RELATIVE_DIR_IN_DATA = "web/deploy"; + private final Fs fs; + + public WebDeployContext() { + this(new Fs()); + } + + @VisibleForTesting + public WebDeployContext(Fs fs) { + this.fs = fs; + } + + public void configureTomcat(Tomcat tomcat, Props props) throws ServletException { + File deployDir = new File(props.nonNullValueAsFile(ProcessProperties.PATH_DATA), RELATIVE_DIR_IN_DATA); + try { + fs.createOrCleanupDir(deployDir); + } catch (IOException e) { + throw new IllegalStateException(format("Fail to create or clean-up directory %s", deployDir.getAbsolutePath()), e); + } + tomcat.addWebapp("/deploy", deployDir.getAbsolutePath()); + } + + static class Fs { + void createOrCleanupDir(File dir) throws IOException { + FileUtils.forceMkdir(dir); + FileUtils.cleanDirectory(dir); + } + } +} 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 f0a128c04d2..bee8e2063dc 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 @@ -19,6 +19,8 @@ */ package org.sonar.server.app; +import java.io.File; +import java.util.Map; import org.apache.catalina.Context; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; @@ -27,9 +29,6 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.process.ProcessProperties; import org.sonar.process.Props; -import java.io.File; -import java.util.Map; - /** * Configures webapp into Tomcat */ @@ -44,6 +43,9 @@ class Webapp { static StandardContext configure(Tomcat tomcat, Props props) { try { + // URL /deploy must serve files deployed during startup into DATA_DIR/web/deploy + new WebDeployContext().configureTomcat(tomcat, props); + StandardContext context = (StandardContext) tomcat.addWebapp(ROOT_CONTEXT_PATH, webappPath(props)); context.setClearReferencesHttpClientKeepAliveThread(false); context.setClearReferencesStatic(false); diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java b/server/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java index 2740d708306..dc41d224733 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java @@ -19,8 +19,13 @@ */ package org.sonar.server.platform; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.CheckForNull; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.FileFilterUtils; import org.picocontainer.Startable; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; @@ -29,15 +34,6 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.process.ProcessProperties; -import javax.annotation.CheckForNull; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - /** * Introspect the filesystem and the classloader to get extension files at startup. * @@ -74,18 +70,6 @@ public class DefaultServerFileSystem implements ServerFileSystem, Startable { if (deployDir == null) { throw new IllegalArgumentException("Web app directory does not exist"); } - try { - FileUtils.forceMkdir(deployDir); - FileFilter fileFilter = FileFilterUtils.directoryFileFilter(); - File[] files = deployDir.listFiles(fileFilter); - if (files != null) { - for (File subDirectory : files) { - FileUtils.cleanDirectory(subDirectory); - } - } - } catch (IOException e) { - throw new IllegalStateException("The following directory can not be created: " + deployDir.getAbsolutePath(), e); - } File deprecated = getDeprecatedPluginsDir(); try { diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java index 444dcd6d61c..cf6bd157eba 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java @@ -41,6 +41,7 @@ import org.sonar.api.platform.Server; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.process.ProcessProperties; +import org.sonar.server.app.WebDeployContext; import static org.sonar.api.CoreProperties.SERVER_BASE_URL; import static org.sonar.api.CoreProperties.SERVER_BASE_URL_DEFAULT_VALUE; @@ -83,7 +84,7 @@ public final class ServerImpl extends Server implements Startable { throw new IllegalStateException("SonarQube home directory is not valid"); } - deployDir = new File(sonarHome, "/web/deploy/"); + deployDir = new File(settings.getString(ProcessProperties.PATH_DATA), WebDeployContext.RELATIVE_DIR_IN_DATA); LOG.info("SonarQube {}", Joiner.on(" / ").skipNulls().join("Server", version, implementationBuild)); diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java index dfbfa4eb581..138b4d29dd7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java @@ -46,9 +46,11 @@ public class EmbeddedTomcatTest { // prepare file system File home = temp.newFolder(); + File data = temp.newFolder(); File webDir = new File(home, "web"); FileUtils.write(new File(home, "web/WEB-INF/web.xml"), "<web-app/>"); props.set("sonar.path.home", home.getAbsolutePath()); + props.set("sonar.path.data", data.getAbsolutePath()); props.set("sonar.path.web", webDir.getAbsolutePath()); props.set("sonar.path.logs", temp.newFolder().getAbsolutePath()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/WebDeployContextTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/WebDeployContextTest.java new file mode 100644 index 00000000000..eac45d9d1fe --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/app/WebDeployContextTest.java @@ -0,0 +1,87 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.app; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; +import org.apache.catalina.startup.Tomcat; +import org.apache.commons.io.FileUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.process.ProcessProperties; +import org.sonar.process.Props; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class WebDeployContextTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + Tomcat tomcat = mock(Tomcat.class); + Properties props = new Properties(); + + @Test + public void create_dir_and_configure_tomcat_context() throws Exception { + File dataDir = temp.newFolder(); + props.setProperty(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath()); + new WebDeployContext().configureTomcat(tomcat, new Props(props)); + + File deployDir = new File(dataDir, "web/deploy"); + assertThat(deployDir).isDirectory().exists(); + verify(tomcat).addWebapp("/deploy", deployDir.getAbsolutePath()); + } + + @Test + public void cleanup_directory_if_already_exists() throws Exception { + File dataDir = temp.newFolder(); + File deployDir = new File(dataDir, "web/deploy"); + FileUtils.touch(new File(deployDir, "foo.txt")); + props.setProperty(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath()); + new WebDeployContext().configureTomcat(tomcat, new Props(props)); + + assertThat(deployDir).isDirectory().exists(); + assertThat(deployDir.listFiles()).isEmpty(); + } + + @Test + public void fail_if_directory_can_not_be_initialized() throws Exception { + File dataDir = temp.newFolder(); + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Fail to create or clean-up directory " + dataDir.getAbsolutePath()); + + props.setProperty(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath()); + WebDeployContext.Fs fs = mock(WebDeployContext.Fs.class); + doThrow(new IOException()).when(fs).createOrCleanupDir(any(File.class)); + + new WebDeployContext(fs).configureTomcat(tomcat, new Props(props)); + + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/WebappTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/WebappTest.java index 197ed81f387..8b8a2f2a935 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/app/WebappTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/app/WebappTest.java @@ -20,13 +20,16 @@ package org.sonar.server.app; import java.io.File; +import java.io.IOException; import java.util.Properties; import org.apache.catalina.Context; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.process.ProcessProperties; import org.sonar.process.Props; import static org.assertj.core.api.Assertions.assertThat; @@ -44,6 +47,11 @@ public class WebappTest { Props props = new Props(new Properties()); + @Before + public void initDataDir() throws Exception { + props.set(ProcessProperties.PATH_DATA, temp.newFolder("data").getAbsolutePath()); + } + @Test public void fail_on_error() throws Exception { File webDir = temp.newFolder("web"); diff --git a/server/sonar-web/src/main/webapp/deploy/readme.txt b/server/sonar-web/src/main/webapp/deploy/readme.txt deleted file mode 100644 index a79464af707..00000000000 --- a/server/sonar-web/src/main/webapp/deploy/readme.txt +++ /dev/null @@ -1 +0,0 @@ -Please note that this file must not be deleted.
\ No newline at end of file |