@@ -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); | |||
} | |||
} | |||
} |
@@ -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); |
@@ -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 { |
@@ -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)); | |||
@@ -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()); | |||
@@ -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)); | |||
} | |||
} |
@@ -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"); |
@@ -1 +0,0 @@ | |||
Please note that this file must not be deleted. |