diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-01-13 11:24:01 +0100 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-01-18 11:16:44 +0100 |
commit | e7c4a306ac47843029d183d8e3f5ca7730184cf2 (patch) | |
tree | d0ad97d750a92e90c60c280a856f6a2b75a1b6b5 /sonar-application/src/main/java | |
parent | 5e12a8cf6011e4f95405a1f8abeee38c92245141 (diff) | |
download | sonarqube-e7c4a306ac47843029d183d8e3f5ca7730184cf2.tar.gz sonarqube-e7c4a306ac47843029d183d8e3f5ca7730184cf2.zip |
SONAR-7168 fileSystem must be reset during a restart
deletion of temp directory is required for uninstalling plugins but also to cleanly start web server (eg. deleting unsuccessfully processed analysis reports)
Diffstat (limited to 'sonar-application/src/main/java')
3 files changed, 133 insertions, 49 deletions
diff --git a/sonar-application/src/main/java/org/sonar/application/App.java b/sonar-application/src/main/java/org/sonar/application/App.java index e09899b1fa4..ca2f98d62b8 100644 --- a/sonar-application/src/main/java/org/sonar/application/App.java +++ b/sonar-application/src/main/java/org/sonar/application/App.java @@ -39,8 +39,8 @@ public class App implements Stoppable { private final Monitor monitor; - public App(File tempDir) { - this(Monitor.create(tempDir)); + public App(AppFileSystem appFileSystem, boolean watchForHardStop) { + this(Monitor.create(appFileSystem, watchForHardStop)); } App(Monitor monitor) { @@ -48,14 +48,11 @@ public class App implements Stoppable { } public void start(Props props) { - if (props.valueAsBoolean(ProcessProperties.ENABLE_STOP_COMMAND, false)) { - monitor.watchForHardStop(); - } monitor.start(createCommands(props)); monitor.awaitTermination(); } - private List<JavaCommand> createCommands(Props props) { + private static List<JavaCommand> createCommands(Props props) { List<JavaCommand> commands = new ArrayList<>(); File homeDir = props.nonNullValueAsFile(ProcessProperties.PATH_HOME); JavaCommand elasticsearch = new JavaCommand("search"); @@ -102,11 +99,14 @@ public class App implements Stoppable { CommandLineParser cli = new CommandLineParser(); Properties rawProperties = cli.parseArguments(args); Props props = new PropsBuilder(rawProperties, new JdbcSettings()).build(); + AppFileSystem appFileSystem = new AppFileSystem(props); + appFileSystem.verifyProps(); AppLogging logging = new AppLogging(); logging.configure(props); - File tempDir = props.nonNullValueAsFile(ProcessProperties.PATH_TEMP); - App app = new App(tempDir); + // used by orchestrator + boolean watchForHardStop = props.valueAsBoolean(ProcessProperties.ENABLE_STOP_COMMAND, false); + App app = new App(appFileSystem, watchForHardStop); app.start(props); } diff --git a/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java b/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java new file mode 100644 index 00000000000..32f563737b2 --- /dev/null +++ b/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java @@ -0,0 +1,120 @@ +/* + * 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.application; + +import java.io.File; +import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.process.Props; +import org.sonar.process.monitor.FileSystem; + +import static org.apache.commons.io.FileUtils.deleteQuietly; +import static org.apache.commons.io.FileUtils.forceMkdir; +import static org.sonar.process.ProcessProperties.PATH_DATA; +import static org.sonar.process.ProcessProperties.PATH_HOME; +import static org.sonar.process.ProcessProperties.PATH_LOGS; +import static org.sonar.process.ProcessProperties.PATH_TEMP; +import static org.sonar.process.ProcessProperties.PATH_WEB; + +public class AppFileSystem implements FileSystem { + private static final Logger LOG = LoggerFactory.getLogger(AppFileSystem.class); + + private static final String DEFAULT_DATA_DIRECTORY_NAME = "data"; + private static final String DEFAULT_WEB_DIRECTORY_NAME = "web"; + private static final String DEFAULT_LOGS_DIRECTORY_NAME = "logs"; + private static final String DEFAULT_TEMP_DIRECTORY_NAME = "temp"; + + private final Props props; + private final File homeDir; + private boolean initialized = false; + + public AppFileSystem(Props props) { + this.props = props; + this.homeDir = props.nonNullValueAsFile(PATH_HOME); + } + + public void verifyProps() { + ensurePropertyIsAbsolutePath(props, PATH_DATA, DEFAULT_DATA_DIRECTORY_NAME); + ensurePropertyIsAbsolutePath(props, PATH_WEB, DEFAULT_WEB_DIRECTORY_NAME); + ensurePropertyIsAbsolutePath(props, PATH_LOGS, DEFAULT_LOGS_DIRECTORY_NAME); + ensurePropertyIsAbsolutePath(props, PATH_TEMP, DEFAULT_TEMP_DIRECTORY_NAME); + this.initialized = true; + } + + /** + * Must be called after {@link #verifyProps()} + */ + @Override + public void reset() throws IOException { + if (!initialized) { + throw new IllegalStateException("method verifyProps must be called first"); + } + ensureDirectoryExists(props, PATH_DATA); + ensureDirectoryExists(props, PATH_WEB); + ensureDirectoryExists(props, PATH_LOGS); + createOrCleanDirectory(props, PATH_TEMP); + } + + @Override + public File getTempDir() { + return props.nonNullValueAsFile(PATH_TEMP); + } + + private File ensurePropertyIsAbsolutePath(Props props, String propKey, String defaultRelativePath) { + String path = props.value(propKey, defaultRelativePath); + File d = new File(path); + if (!d.isAbsolute()) { + d = new File(homeDir, path); + LOG.trace("Overriding property {} from relative path '{}' to absolute path '{}'", path, d.getAbsolutePath()); + props.set(propKey, d.getAbsolutePath()); + } + return d; + } + + private static boolean ensureDirectoryExists(Props props, String propKey) throws IOException { + File dir = props.nonNullValueAsFile(propKey); + if (dir.exists()) { + ensureIsNotAFile(propKey, dir); + return false; + } else { + LOG.trace("forceMkdir {}", dir.getAbsolutePath()); + forceMkdir(dir); + ensureIsNotAFile(propKey, dir); + return true; + } + } + + private static void ensureIsNotAFile(String propKey, File dir) { + if (!dir.isDirectory()) { + throw new IllegalStateException(String.format("Property '%s' is not valid, not a directory: %s", + propKey, dir.getAbsolutePath())); + } + } + + private static void createOrCleanDirectory(Props props, String propKey) throws IOException { + File dir = props.nonNullValueAsFile(propKey); + LOG.info("Deleting and/or creating temp directory {}", dir.getAbsolutePath()); + if (!ensureDirectoryExists(props, propKey)) { + deleteQuietly(dir); + forceMkdir(dir); + } + } +} diff --git a/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java b/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java index d915e1609ad..1e2d25778e2 100644 --- a/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java +++ b/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java @@ -19,12 +19,6 @@ */ package org.sonar.application; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.sonar.process.ConfigurationUtils; -import org.sonar.process.ProcessProperties; -import org.sonar.process.Props; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -33,6 +27,10 @@ import java.io.Reader; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.Properties; +import org.apache.commons.io.IOUtils; +import org.sonar.process.ConfigurationUtils; +import org.sonar.process.ProcessProperties; +import org.sonar.process.Props; class PropsBuilder { @@ -51,8 +49,7 @@ class PropsBuilder { } /** - * Load optional conf/sonar.properties, interpolates environment variables and - * initializes file system + * Load optional conf/sonar.properties, interpolates environment variables */ Props build() throws IOException { Properties p = loadPropertiesFile(homeDir); @@ -66,12 +63,6 @@ class PropsBuilder { Props props = new Props(p); ProcessProperties.completeDefaults(props); - // init file system - initExistingDir(props, ProcessProperties.PATH_DATA, "data"); - initExistingDir(props, ProcessProperties.PATH_WEB, "web"); - initExistingDir(props, ProcessProperties.PATH_LOGS, "logs"); - initTempDir(props); - // check JDBC properties and set path to driver jdbcSettings.checkAndComplete(homeDir, props); @@ -96,31 +87,4 @@ class PropsBuilder { } return p; } - - private void initTempDir(Props props) throws IOException { - File dir = configureDir(props, ProcessProperties.PATH_TEMP, "temp"); - FileUtils.deleteQuietly(dir); - FileUtils.forceMkdir(dir); - } - - private void initExistingDir(Props props, String propKey, String defaultRelativePath) throws IOException { - File dir = configureDir(props, propKey, defaultRelativePath); - if (!dir.exists()) { - FileUtils.forceMkdir(dir); - } - if (!dir.isDirectory()) { - throw new IllegalStateException(String.format("Property '%s' is not valid, not a directory: %s", - propKey, dir.getAbsolutePath())); - } - } - - private File configureDir(Props props, String propKey, String defaultRelativePath) { - String path = props.value(propKey, defaultRelativePath); - File d = new File(path); - if (!d.isAbsolute()) { - d = new File(homeDir, path); - } - props.set(propKey, d.getAbsolutePath()); - return d; - } } |