From 39ecd1902afc8922811f97524dfa77a86912508f Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Wed, 23 Jul 2014 00:32:58 +0200 Subject: [PATCH] SONAR-4898 few improvements --- .../main/java/org/sonar/process/Process.java | 23 +++----- .../org/sonar/process/ProcessWrapper.java | 18 +----- .../main/java/org/sonar/process/Props.java | 30 +++++----- .../src/main/resources/logback.xml | 2 +- .../org/sonar/search/ElasticSearchTest.java | 1 - .../main/java/org/sonar/server/app/Env.java | 16 ----- .../org/sonar/server/app/ServerProcess.java | 1 - .../java/org/sonar/server/app/Webapp.java | 2 +- .../org/sonar/application/Installation.java | 58 +++++++------------ .../org/sonar/application/StartServer.java | 4 +- 10 files changed, 51 insertions(+), 104 deletions(-) diff --git a/server/sonar-process/src/main/java/org/sonar/process/Process.java b/server/sonar-process/src/main/java/org/sonar/process/Process.java index b3824c79606..cc064b758b7 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/Process.java +++ b/server/sonar-process/src/main/java/org/sonar/process/Process.java @@ -19,6 +19,7 @@ */ package org.sonar.process; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,24 +42,16 @@ import java.util.concurrent.TimeUnit; public abstract class Process implements ProcessMXBean { - public static final String SONAR_HOME = "SONAR_HOME"; - - public static final String JAVA_OPS = "javaOps"; public static final String NAME_PROPERTY = "pName"; public static final String PORT_PROPERTY = "pPort"; - public static final String MISSING_NAME_ARGUMENT = "Missing Name argument"; - public static final String SONAR_HOME_IS_NOT_SET = "variable SONAR_HOME is not set."; - public static final String SONAR_HOME_DOES_NOT_EXIST = "Directory SONAR_HOME does not exist"; - public static final String SONAR_HOME_IS_NOT_WRITABLE = "Directory SONAR_HOME is not writable"; - private final static Logger LOGGER = LoggerFactory.getLogger(Process.class); - protected Long lastPing; + private Long lastPing; - String name; - Integer port; + private String name; + private Integer port; protected final Props props; private Thread shutdownHook; @@ -89,10 +82,14 @@ public abstract class Process implements ProcessMXBean { } Properties properties = new Properties(); + FileReader reader = null; try { - properties.load(new FileReader(propertyFile)); + reader = new FileReader(propertyFile); + properties.load(reader); } catch (IOException e) { throw new IllegalStateException("Could not read properties from file '" + args[0] + "'", e); + } finally { + IOUtils.closeQuietly(reader); } props = new Props(properties); init(); @@ -104,7 +101,6 @@ public abstract class Process implements ProcessMXBean { } private void init() { - // Loading all Properties from file this.name = props.of(NAME_PROPERTY, null); this.port = props.intOf(PORT_PROPERTY); @@ -124,7 +120,6 @@ public abstract class Process implements ProcessMXBean { throw new IllegalStateException("Process is not a compliant MBean", e); } - shutdownHook = new Thread(new Runnable() { @Override public void run() { diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java index 435c84ca355..cb1f77c11f6 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java +++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java @@ -60,7 +60,7 @@ public class ProcessWrapper extends Thread { private final List javaOpts = new ArrayList(); private final List classpath = new ArrayList(); private final Map envProperties = new HashMap(); - private final Map properties = new HashMap(); + private final Properties properties = new Properties(); private File workDir; private File propertiesFile; private java.lang.Process process; @@ -82,21 +82,9 @@ public class ProcessWrapper extends Thread { return this; } - public ProcessWrapper setProperty(String key, String value) { - properties.put(key, value); - return this; - } - - public ProcessWrapper setProperties(Map args) { + public ProcessWrapper setProperties(Properties p) { properties.clear(); - properties.putAll(args); - return this; - } - - public ProcessWrapper setJavaOpts(List opts) { - for (String command : opts) { - addJavaOpts(command); - } + properties.putAll(p); return this; } diff --git a/server/sonar-process/src/main/java/org/sonar/process/Props.java b/server/sonar-process/src/main/java/org/sonar/process/Props.java index 506f6b927f1..21bd8842e3a 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/Props.java +++ b/server/sonar-process/src/main/java/org/sonar/process/Props.java @@ -19,20 +19,27 @@ */ package org.sonar.process; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.Map; import java.util.Properties; public class Props { private final Properties props; + private final Encryption encryption; public Props(Properties props) { this.props = props; + this.encryption = new Encryption(props.getProperty(AesCipher.ENCRYPTION_SECRET_KEY_PATH)); } + @CheckForNull public String of(String key) { - return props.getProperty(key); + String value = props.getProperty(key); + if (value != null && encryption.isEncrypted(value)) { + value = encryption.decrypt(value); + } + return value; } public String of(String key, @Nullable String defaultValue) { @@ -67,23 +74,12 @@ public class Props { return i == null ? defaultValue : i; } - public Properties properties() { + public Properties cryptedProperties() { return props; } - - static Properties decrypt(Properties properties) { - Encryption encryption = new Encryption(properties.getProperty(AesCipher.ENCRYPTION_SECRET_KEY_PATH)); - Properties result = new Properties(); - - for (Map.Entry entry : properties.entrySet()) { - String key = (String) entry.getKey(); - String value = (String) entry.getValue(); - if (encryption.isEncrypted(value)) { - value = encryption.decrypt(value); - } - result.setProperty(key, value); - } - return result; + public Props set(String key, @Nullable String value) { + props.setProperty(key, value); + return this; } } diff --git a/server/sonar-search/src/main/resources/logback.xml b/server/sonar-search/src/main/resources/logback.xml index 281bccb3d09..25d1932da9d 100644 --- a/server/sonar-search/src/main/resources/logback.xml +++ b/server/sonar-search/src/main/resources/logback.xml @@ -41,7 +41,7 @@ - + diff --git a/server/sonar-search/src/test/java/org/sonar/search/ElasticSearchTest.java b/server/sonar-search/src/test/java/org/sonar/search/ElasticSearchTest.java index a53268205bd..e8185c549a4 100644 --- a/server/sonar-search/src/test/java/org/sonar/search/ElasticSearchTest.java +++ b/server/sonar-search/src/test/java/org/sonar/search/ElasticSearchTest.java @@ -82,7 +82,6 @@ public class ElasticSearchTest { @Test public void can_connect() throws SocketException { Properties properties = new Properties(); - properties.setProperty(Process.SONAR_HOME, FileUtils.getTempDirectoryPath()); properties.setProperty(Process.NAME_PROPERTY, "ES"); properties.setProperty("sonar.path.data", tempDirectory.getAbsolutePath()); properties.setProperty(ElasticSearch.ES_PORT_PROPERTY, Integer.toString(freeESPort)); diff --git a/server/sonar-server-app/src/main/java/org/sonar/server/app/Env.java b/server/sonar-server-app/src/main/java/org/sonar/server/app/Env.java index 885fbbad7b1..a9b9f7c278c 100644 --- a/server/sonar-server-app/src/main/java/org/sonar/server/app/Env.java +++ b/server/sonar-server-app/src/main/java/org/sonar/server/app/Env.java @@ -23,7 +23,6 @@ import org.apache.commons.io.FileUtils; import org.sonar.process.Props; import java.io.File; -import java.io.IOException; class Env { @@ -51,19 +50,4 @@ class Env { dir.mkdirs(); return dir; } - - /** - * This check is required in order to provide more meaningful message than JRuby - see SONAR-2715 - */ - void verifyWritableTempDir() { - File file = null; - try { - file = File.createTempFile("sonarqube-check", "tmp"); - } catch (IOException e) { - throw new IllegalStateException("Unable to create file in temporary directory, please check existence " + - "and permissions of: " + FileUtils.getTempDirectory(), e); - } finally { - FileUtils.deleteQuietly(file); - } - } } diff --git a/server/sonar-server-app/src/main/java/org/sonar/server/app/ServerProcess.java b/server/sonar-server-app/src/main/java/org/sonar/server/app/ServerProcess.java index 287176a828d..9006705365e 100644 --- a/server/sonar-server-app/src/main/java/org/sonar/server/app/ServerProcess.java +++ b/server/sonar-server-app/src/main/java/org/sonar/server/app/ServerProcess.java @@ -27,7 +27,6 @@ public class ServerProcess extends org.sonar.process.Process { super(args); Logging.init(); Env env = new Env(props); - env.verifyWritableTempDir(); this.tomcat = new EmbeddedTomcat(env); } diff --git a/server/sonar-server-app/src/main/java/org/sonar/server/app/Webapp.java b/server/sonar-server-app/src/main/java/org/sonar/server/app/Webapp.java index e20500f15bd..9f98faf2ec6 100644 --- a/server/sonar-server-app/src/main/java/org/sonar/server/app/Webapp.java +++ b/server/sonar-server-app/src/main/java/org/sonar/server/app/Webapp.java @@ -40,7 +40,7 @@ class Webapp { context.setConfigFile(env.file("web/META-INF/context.xml").toURI().toURL()); context.addParameter(PROPERTY_LOG_PROFILING_LEVEL, props.of(PROPERTY_LOG_PROFILING_LEVEL, "NONE")); context.addParameter(PROPERTY_LOG_CONSOLE, props.of(PROPERTY_LOG_CONSOLE, "false")); - for (Map.Entry entry : props.properties().entrySet()) { + for (Map.Entry entry : props.cryptedProperties().entrySet()) { String key = entry.getKey().toString(); if (key.startsWith("sonar.")) { context.addParameter(key, entry.getValue().toString()); diff --git a/sonar-application/src/main/java/org/sonar/application/Installation.java b/sonar-application/src/main/java/org/sonar/application/Installation.java index c6b0f2693fb..ce9c451e4b0 100644 --- a/sonar-application/src/main/java/org/sonar/application/Installation.java +++ b/sonar-application/src/main/java/org/sonar/application/Installation.java @@ -24,8 +24,8 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.process.ConfigurationUtils; import org.sonar.process.NetworkUtils; +import org.sonar.process.Props; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -33,8 +33,6 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; import java.util.Properties; public class Installation { @@ -42,7 +40,7 @@ public class Installation { private final File homeDir; private final File tempDir, dataDir, logsDir, webDir; - private final Map props; + private final Props props; Installation() throws URISyntaxException, IOException { // home dir guessed with location of lib/sonar-application.jar @@ -52,8 +50,8 @@ public class Installation { props = initProps(homeDir); // init file system + this.tempDir = initTempDir("sonar.path.temp", "temp"); this.dataDir = existingDir("sonar.path.data", "data"); - this.tempDir = freshDir("sonar.path.temp", "temp"); this.logsDir = existingDir("sonar.path.logs", "logs"); this.webDir = existingDir("sonar.path.web", "web"); @@ -63,7 +61,7 @@ public class Installation { /** * Load conf/sonar.properties */ - private static Map initProps(File homeDir) throws IOException { + private static Props initProps(File homeDir) throws IOException { Properties p = new Properties(); File propsFile = new File(homeDir, "conf/sonar.properties"); if (propsFile.exists()) { @@ -78,27 +76,19 @@ public class Installation { } p.putAll(System.getenv()); p.putAll(System.getProperties()); - p = ConfigurationUtils.interpolateEnvVariables(p); - Map result = new HashMap(); - for (Map.Entry entry : p.entrySet()) { - Object val = entry.getValue(); - if (val != null) { - result.put(entry.getKey().toString(), val.toString()); - } - } - result.put("sonar.path.home", homeDir.getAbsolutePath()); - return result; + p.setProperty("sonar.path.home", homeDir.getAbsolutePath()); + return new Props(p); } private void initElasticsearch() { - String port = props.get("sonar.es.port"); - if (port == null || "".equals(port) || "0".equals(port)) { - props.put("sonar.es.port", String.valueOf(NetworkUtils.freePort())); + int port = props.intOf("sonar.es.port", 0); + if (port <= 0) { + props.set("sonar.es.port", String.valueOf(NetworkUtils.freePort())); } - if (props.get("sonar.es.cluster.name") == null) { - props.put("sonar.es.cluster.name", "sonarqube"); + if (props.of("sonar.es.cluster.name") == null) { + props.set("sonar.es.cluster.name", "sonarqube"); } - props.put("sonar.es.type", "TRANSPORT"); + props.set("sonar.es.type", "TRANSPORT"); } File homeDir() { @@ -118,10 +108,15 @@ public class Installation { return FilenameUtils.concat(dir.getAbsolutePath(), "*"); } - private File freshDir(String propKey, String defaultRelativePath) throws IOException { + private File initTempDir(String propKey, String defaultRelativePath) throws IOException { File dir = configuredDir(propKey, defaultRelativePath); FileUtils.deleteQuietly(dir); FileUtils.forceMkdir(dir); + + // verify that temp directory is writable + File tempFile = File.createTempFile("check", "tmp", dir); + FileUtils.deleteQuietly(tempFile); + return dir; } @@ -142,25 +137,16 @@ public class Installation { if (!d.isAbsolute()) { d = new File(homeDir, path); } - props.put(propKey, d.getAbsolutePath()); + props.set(propKey, d.getAbsolutePath()); return d; } - Map props() { - return props; - } - @CheckForNull String prop(String key, @Nullable String defaultValue) { - String s = props.get(key); - return s != null ? s : defaultValue; + return props.of(key, defaultValue); } - void logInfo(String message) { - System.out.println(message); - } - - void logError(String message) { - System.err.println(message); + public Props props() { + return props; } } diff --git a/sonar-application/src/main/java/org/sonar/application/StartServer.java b/sonar-application/src/main/java/org/sonar/application/StartServer.java index 851c69070a1..e03235977d1 100644 --- a/sonar-application/src/main/java/org/sonar/application/StartServer.java +++ b/sonar-application/src/main/java/org/sonar/application/StartServer.java @@ -51,7 +51,7 @@ public class StartServer { .addJavaOpts("-Djava.io.tmpdir=" + installation.tempDir().getAbsolutePath()) .addJavaOpts("-Dsonar.path.logs=" + installation.logsDir().getAbsolutePath()) .setClassName("org.sonar.search.ElasticSearch") - .setProperties(installation.props()) + .setProperties(installation.props().cryptedProperties()) .addClasspath(installation.starPath("lib/common")) .addClasspath(installation.starPath("lib/search")) .execute(); @@ -67,7 +67,7 @@ public class StartServer { .addJavaOpts("-Djava.io.tmpdir=" + installation.tempDir().getAbsolutePath()) .addJavaOpts("-Dsonar.path.logs=" + installation.logsDir().getAbsolutePath()) .setClassName("org.sonar.server.app.ServerProcess") - .setProperties(installation.props()) + .setProperties(installation.props().cryptedProperties()) .addClasspath(installation.starPath("extensions/jdbc-driver/mysql")) .addClasspath(installation.starPath("extensions/jdbc-driver/mssql")) .addClasspath(installation.starPath("extensions/jdbc-driver/oracle")) -- 2.39.5