aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-application/src/main/java
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-02-23 18:32:30 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-02-24 21:14:15 +0100
commit132100250bc9dabdb0e28944e7d2f0e8629c6102 (patch)
tree08e608fa390d33e3fb9a55f7ebd92fe74d9ef45c /sonar-application/src/main/java
parentcfe7a59ac8d45c4d1d7def3923c67c5b48f70161 (diff)
downloadsonarqube-132100250bc9dabdb0e28944e7d2f0e8629c6102.tar.gz
sonarqube-132100250bc9dabdb0e28944e7d2f0e8629c6102.zip
SONAR-7937 restart reloads sonar.properties
but changes of FileSystem related properties are not supported and will make restart fail
Diffstat (limited to 'sonar-application/src/main/java')
-rw-r--r--sonar-application/src/main/java/org/sonar/application/App.java88
-rw-r--r--sonar-application/src/main/java/org/sonar/application/AppFileSystem.java19
2 files changed, 89 insertions, 18 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 d6c3b843a85..8fc3ba6f5b3 100644
--- a/sonar-application/src/main/java/org/sonar/application/App.java
+++ b/sonar-application/src/main/java/org/sonar/application/App.java
@@ -19,10 +19,14 @@
*/
package org.sonar.application;
+import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,27 +45,46 @@ import static org.sonar.process.ProcessId.APP;
*/
public class App implements Stoppable {
+ private final Properties commandLineArguments;
+ private final Function<Properties, Props> propsSupplier;
private final JavaCommandFactory javaCommandFactory;
private final Monitor monitor;
+ private final Supplier<List<JavaCommand>> javaCommandSupplier;
- public App(AppFileSystem appFileSystem, boolean watchForHardStop) {
- this(Monitor.newMonitorBuilder()
+ private App(Properties commandLineArguments) {
+ this.commandLineArguments = commandLineArguments;
+ this.propsSupplier = properties -> new PropsBuilder(properties, new JdbcSettings()).build();
+ this.javaCommandFactory = new JavaCommandFactoryImpl();
+ Props props = propsSupplier.apply(commandLineArguments);
+
+ AppFileSystem appFileSystem = new AppFileSystem(props);
+ appFileSystem.verifyProps();
+ AppLogging logging = new AppLogging();
+ logging.configure(props);
+
+ // used by orchestrator
+ boolean watchForHardStop = props.valueAsBoolean(ProcessProperties.ENABLE_STOP_COMMAND, false);
+ this.monitor = Monitor.newMonitorBuilder()
.setProcessNumber(APP.getIpcIndex())
.setFileSystem(appFileSystem)
.setWatchForHardStop(watchForHardStop)
.setWaitForOperational()
.addListener(new AppLifecycleListener())
- .build(),
- new JavaCommandFactoryImpl());
+ .build();
+ this.javaCommandSupplier = new ReloadableCommandSupplier(props, appFileSystem::ensureUnchangedConfiguration);
}
- App(Monitor monitor, JavaCommandFactory javaCommandFactory) {
+ @VisibleForTesting
+ App(Properties commandLineArguments, Function<Properties, Props> propsSupplier, Monitor monitor, CheckFSConfigOnReload checkFsConfigOnReload, JavaCommandFactory javaCommandFactory) {
+ this.commandLineArguments = commandLineArguments;
+ this.propsSupplier = propsSupplier;
this.javaCommandFactory = javaCommandFactory;
this.monitor = monitor;
+ this.javaCommandSupplier = new ReloadableCommandSupplier(propsSupplier.apply(commandLineArguments), checkFsConfigOnReload);
}
- public void start(Props props) throws InterruptedException {
- monitor.start(() -> createCommands(props));
+ public void start() throws InterruptedException {
+ monitor.start(javaCommandSupplier);
monitor.awaitTermination();
}
@@ -96,21 +119,16 @@ public class App implements Stoppable {
public static void main(String[] args) throws InterruptedException {
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);
- // used by orchestrator
- boolean watchForHardStop = props.valueAsBoolean(ProcessProperties.ENABLE_STOP_COMMAND, false);
- App app = new App(appFileSystem, watchForHardStop);
- app.start(props);
+ App app = new App(rawProperties);
+ app.start();
}
@Override
public void stopAsync() {
- monitor.stop();
+ if (monitor != null) {
+ monitor.stop();
+ }
}
private static class AppLifecycleListener implements Lifecycle.LifecycleListener {
@@ -123,4 +141,40 @@ public class App implements Stoppable {
}
}
}
+
+ @FunctionalInterface
+ interface CheckFSConfigOnReload extends Consumer<Props> {
+
+ }
+
+ private class ReloadableCommandSupplier implements Supplier<List<JavaCommand>> {
+ private final Props initialProps;
+ private final CheckFSConfigOnReload checkFsConfigOnReload;
+ private boolean initialPropsConsumed = false;
+
+ ReloadableCommandSupplier(Props initialProps, CheckFSConfigOnReload checkFsConfigOnReload) {
+ this.initialProps = initialProps;
+ this.checkFsConfigOnReload = checkFsConfigOnReload;
+ }
+
+ @Override
+ public List<JavaCommand> get() {
+ if (!initialPropsConsumed) {
+ initialPropsConsumed = true;
+ return createCommands(this.initialProps);
+ }
+ return recreateCommands();
+ }
+
+ private List<JavaCommand> recreateCommands() {
+ Props reloadedProps = propsSupplier.apply(commandLineArguments);
+ AppFileSystem appFileSystem = new AppFileSystem(reloadedProps);
+ appFileSystem.verifyProps();
+ checkFsConfigOnReload.accept(reloadedProps);
+ AppLogging logging = new AppLogging();
+ logging.configure(reloadedProps);
+
+ return createCommands(reloadedProps);
+ }
+ }
}
diff --git a/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java b/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java
index d8b0497d504..9b07583314e 100644
--- a/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java
+++ b/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java
@@ -29,12 +29,14 @@ import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
+import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.process.AllProcessesCommands;
import org.sonar.process.Props;
import org.sonar.process.monitor.FileSystem;
+import static java.lang.String.format;
import static java.nio.file.FileVisitResult.CONTINUE;
import static org.apache.commons.io.FileUtils.forceMkdir;
import static org.sonar.process.FileUtils.deleteDirectory;
@@ -118,7 +120,7 @@ public class AppFileSystem implements FileSystem {
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",
+ throw new IllegalStateException(format("Property '%s' is not valid, not a directory: %s",
propKey, dir.getAbsolutePath()));
}
}
@@ -132,6 +134,21 @@ public class AppFileSystem implements FileSystem {
return dir;
}
+ public void ensureUnchangedConfiguration(Props newProps) {
+ verifyUnchanged(newProps, PATH_DATA, DEFAULT_DATA_DIRECTORY_NAME);
+ verifyUnchanged(newProps, PATH_WEB, DEFAULT_WEB_DIRECTORY_NAME);
+ verifyUnchanged(newProps, PATH_LOGS, DEFAULT_LOGS_DIRECTORY_NAME);
+ verifyUnchanged(newProps, PATH_TEMP, DEFAULT_TEMP_DIRECTORY_NAME);
+ }
+
+ private void verifyUnchanged(Props newProps, String propKey, String defaultRelativePath) {
+ String initialValue = props.value(propKey, defaultRelativePath);
+ String newValue = newProps.value(propKey, defaultRelativePath);
+ if (!Objects.equals(newValue, initialValue)) {
+ throw new IllegalStateException(format("Change of property '%s' is not supported ('%s'=> '%s')", propKey, initialValue, newValue));
+ }
+ }
+
private static class CleanTempDirFileVisitor extends SimpleFileVisitor<Path> {
private static final Path SHAREDMEMORY_FILE = Paths.get("sharedmemory");
public static final int VISIT_MAX_DEPTH = 1;