summaryrefslogtreecommitdiffstats
path: root/sonar-application/src/main/java
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-01-13 11:24:01 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-01-18 11:16:44 +0100
commite7c4a306ac47843029d183d8e3f5ca7730184cf2 (patch)
treed0ad97d750a92e90c60c280a856f6a2b75a1b6b5 /sonar-application/src/main/java
parent5e12a8cf6011e4f95405a1f8abeee38c92245141 (diff)
downloadsonarqube-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')
-rw-r--r--sonar-application/src/main/java/org/sonar/application/App.java16
-rw-r--r--sonar-application/src/main/java/org/sonar/application/AppFileSystem.java120
-rw-r--r--sonar-application/src/main/java/org/sonar/application/PropsBuilder.java46
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;
- }
}