aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2014-07-22 17:59:49 +0200
committerStephane Gamard <stephane.gamard@searchbox.com>2014-07-23 15:34:05 +0200
commit1fd258f12f256aea2359d3469f9e6308608485f2 (patch)
treee6e58dbabead55b15cbd1e1b247c177932556498
parent74102a370cf912472957b896ce2141bab76b9535 (diff)
downloadsonarqube-1fd258f12f256aea2359d3469f9e6308608485f2.tar.gz
sonarqube-1fd258f12f256aea2359d3469f9e6308608485f2.zip
SONAR-4898 some refactoring
-rw-r--r--server/sonar-process/pom.xml9
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/AesCipher.java12
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Encryption.java10
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Process.java29
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java320
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Props.java18
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java40
-rw-r--r--server/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java2
-rw-r--r--server/sonar-search/src/test/java/org/sonar/search/ElasticSearchTest.java2
-rw-r--r--sonar-application/src/main/assembly/conf/sonar.properties18
-rw-r--r--sonar-application/src/main/assembly/conf/wrapper.conf30
-rw-r--r--sonar-application/src/main/java/org/sonar/application/AesCipher.java138
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Base64Cipher.java35
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Cipher.java26
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Encryption.java66
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Env.java75
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Props.java117
-rw-r--r--sonar-application/src/main/java/org/sonar/application/StartServer.java (renamed from sonar-application/src/main/java/org/sonar/application/ForkProcesses.java)46
-rw-r--r--sonar-application/src/test/java/org/sonar/application/AesCipherTest.java186
-rw-r--r--sonar-application/src/test/java/org/sonar/application/EncryptionTest.java59
-rw-r--r--sonar-application/src/test/java/org/sonar/application/EnvTest.java99
-rw-r--r--sonar-application/src/test/java/org/sonar/application/PropsTest.java135
22 files changed, 236 insertions, 1236 deletions
diff --git a/server/sonar-process/pom.xml b/server/sonar-process/pom.xml
index d9626a43316..457068b014c 100644
--- a/server/sonar-process/pom.xml
+++ b/server/sonar-process/pom.xml
@@ -38,10 +38,6 @@
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
@@ -67,5 +63,10 @@
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/server/sonar-process/src/main/java/org/sonar/process/AesCipher.java b/server/sonar-process/src/main/java/org/sonar/process/AesCipher.java
index b17de206349..5b8102c044d 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/AesCipher.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/AesCipher.java
@@ -20,8 +20,6 @@
package org.sonar.process;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Throwables;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
@@ -61,8 +59,10 @@ final class AesCipher extends Cipher {
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CRYPTO_KEY);
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, loadSecretFile());
return new String(Base64.encodeBase64(cipher.doFinal(clearText.getBytes("UTF-8"))));
+ } catch (RuntimeException e) {
+ throw e;
} catch (Exception e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
@@ -73,8 +73,10 @@ final class AesCipher extends Cipher {
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, loadSecretFile());
byte[] cipherData = cipher.doFinal(Base64.decodeBase64(StringUtils.trim(encryptedText)));
return new String(cipherData);
+ } catch (RuntimeException e) {
+ throw e;
} catch (Exception e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
@@ -95,7 +97,6 @@ final class AesCipher extends Cipher {
return loadSecretFileFromFile(path);
}
- @VisibleForTesting
Key loadSecretFileFromFile(@Nullable String path) throws IOException {
if (StringUtils.isBlank(path)) {
throw new IllegalStateException("Secret key not found. Please set the property " + ENCRYPTION_SECRET_KEY_PATH);
@@ -123,7 +124,6 @@ final class AesCipher extends Cipher {
}
}
- @VisibleForTesting
String getPathToSecretKey() {
if (StringUtils.isBlank(pathToSecretKey)) {
pathToSecretKey = new File(FileUtils.getUserDirectoryPath(), ".sonar/sonar-secret.txt").getPath();
diff --git a/server/sonar-process/src/main/java/org/sonar/process/Encryption.java b/server/sonar-process/src/main/java/org/sonar/process/Encryption.java
index 0de37cc4456..cca05e6c780 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/Encryption.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/Encryption.java
@@ -20,9 +20,8 @@
package org.sonar.process;
-import com.google.common.collect.ImmutableMap;
-
import javax.annotation.Nullable;
+import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
@@ -38,14 +37,13 @@ public final class Encryption {
private static final String AES_ALGORITHM = "aes";
private final AesCipher aesCipher;
- private final Map<String, Cipher> ciphers;
+ private final Map<String, Cipher> ciphers = new HashMap<String, Cipher>();
private static final Pattern ENCRYPTED_PATTERN = Pattern.compile("\\{(.*?)\\}(.*)");
public Encryption(@Nullable String pathToSecretKey) {
aesCipher = new AesCipher(pathToSecretKey);
- ciphers = ImmutableMap.of(
- BASE64_ALGORITHM, new Base64Cipher(),
- AES_ALGORITHM, aesCipher);
+ ciphers.put(BASE64_ALGORITHM, new Base64Cipher());
+ ciphers.put(AES_ALGORITHM, aesCipher);
}
public boolean isEncrypted(String value) {
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 d003bf153b9..b3824c79606 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,7 +19,6 @@
*/
package org.sonar.process;
-import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -95,24 +94,20 @@ public abstract class Process implements ProcessMXBean {
} catch (IOException e) {
throw new IllegalStateException("Could not read properties from file '" + args[0] + "'", e);
}
- props = Props.create(properties);
+ props = new Props(properties);
init();
}
- @VisibleForTesting
public Process(Props props) {
this.props = props;
init();
}
private void init() {
-
// Loading all Properties from file
this.name = props.of(NAME_PROPERTY, null);
this.port = props.intOf(PORT_PROPERTY);
- validateSonarHome(props);
-
// Testing required properties
if (StringUtils.isEmpty(this.name)) {
throw new IllegalStateException(MISSING_NAME_ARGUMENT);
@@ -194,24 +189,4 @@ public abstract class Process implements ProcessMXBean {
public final void terminate() {
terminate(false);
}
-
- private void validateSonarHome(Props props) {
-
- // check that we have a SONAR_HOME either in props or in env.
- String sonarHome = props.of(SONAR_HOME, System.getenv(SONAR_HOME));
- if (StringUtils.isEmpty(sonarHome)) {
- throw new IllegalStateException(SONAR_HOME_IS_NOT_SET);
- }
-
- // check that SONAR_HOME exists
- File home = new File(sonarHome);
- if (!home.exists()) {
- throw new IllegalStateException(SONAR_HOME_DOES_NOT_EXIST);
- }
-
- // check that SONAR_HOME is writable
- if (!home.canWrite()) {
- throw new IllegalStateException(SONAR_HOME_IS_NOT_WRITABLE);
- }
- }
-} \ No newline at end of file
+}
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 d2640f827b7..d08163d56fd 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
@@ -19,14 +19,12 @@
*/
package org.sonar.process;
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.Closeables;
-import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.Nullable;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
@@ -42,89 +40,122 @@ import java.io.OutputStream;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.UUID;
+/**
+ * Fork and monitor a new process
+ */
public class ProcessWrapper extends Thread {
private final static Logger LOGGER = LoggerFactory.getLogger(ProcessWrapper.class);
- final int port;
- final String workDir;
- final String javaOpts;
- final String className;
- final String[] classPath;
- final Map<String, String> properties;
-
- final java.lang.Process process;
+ private String processName, className;
+ private int jmxPort = -1;
+ private final List<String> javaOpts = new ArrayList<String>();
+ private final List<String> classpath = new ArrayList<String>();
+ private final Map<String, String> envProperties = new HashMap<String, String>();
+ private final Map<String, String> arguments = new HashMap<String, String>();
+ private File workDir;
+ private File propertiesFile;
+ private java.lang.Process process;
private volatile Thread processThread;
-
private StreamGobbler errorGobbler;
private StreamGobbler outputGobbler;
+ private ProcessMXBean processMXBean;
- final ProcessMXBean processMXBean;
+ public ProcessWrapper(String processName) {
+ this.processThread = this;
+ this.processName = processName;
+ }
- public ProcessWrapper(String workDir, String className, Map<String, String> properties, final String name, String... classPath) {
- this(workDir, null, className, properties, name, className);
- LOGGER.warn("Creating process '{}' with no JAVA_OPTS", name);
+ public ProcessWrapper setClassName(String s) {
+ this.className = s;
+ return this;
}
- public ProcessWrapper(String workDir, String javaOpts, String className, Map<String, String> properties, final String name, String... classPath) {
- super(name);
- this.port = NetworkUtils.freePort();
- LOGGER.info("Creating Process for '{}' with workDir: '{}' and monitoring port: {}", name, workDir, port);
- this.workDir = workDir;
- this.javaOpts = javaOpts;
- this.className = className;
- this.classPath = classPath;
- this.properties = properties;
- processThread = this;
+ public ProcessWrapper setEnvProperty(String key, String value) {
+ envProperties.put(key, value);
+ return this;
+ }
- this.process = executeProcess();
+ public ProcessWrapper setArgument(String key, String value) {
+ arguments.put(key, value);
+ return this;
+ }
- processMXBean = waitForJMX(name, port);
+ public ProcessWrapper setArguments(Map<String, String> args) {
+ arguments.clear();
+ arguments.putAll(args);
+ return this;
}
- public ProcessMXBean getProcessMXBean() {
- return processMXBean;
+ public ProcessWrapper setJavaOpts(List<String> opts) {
+ for (String command : opts) {
+ addJavaOpts(command);
+ }
+ return this;
}
- private ProcessMXBean waitForJMX(String name, Integer port) {
+ public ProcessWrapper addJavaOpts(String s) {
+ Collections.addAll(javaOpts, s.split(" "));
+ return this;
+ }
- Exception exception = null;
- for (int i = 0; i < 5; i++) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- throw new IllegalStateException("Could not connect to JMX server", e);
- }
- LOGGER.info("Try #{} to connect to JMX server for process '{}'", i, name);
- try {
- String protocol = "rmi";
- String path = "/jndi/rmi://" + InetAddress.getLocalHost().getHostAddress() + ":" + port + "/jmxrmi";
- JMXServiceURL jmxUrl = new JMXServiceURL(protocol, InetAddress.getLocalHost().getHostAddress(), port, path);
- JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxUrl, null);
- MBeanServerConnection mBeanServer = jmxConnector.getMBeanServerConnection();
- ProcessMXBean bean = JMX.newMBeanProxy(mBeanServer, Process.objectNameFor(name), ProcessMXBean.class);
- LOGGER.info("ProcessWrapper::waitForJMX -- Connected to JMX Server with URL: {}", jmxUrl.toString());
- return bean;
- } catch (MalformedURLException e) {
- throw new IllegalStateException("JMXUrl is not valid", e);
- } catch (UnknownHostException e) {
- throw new IllegalStateException("Could not get hostname", e);
- } catch (IOException e) {
- exception = e;
- }
- }
- throw new IllegalStateException("Could not connect to JMX service", exception);
+ public ProcessWrapper setClasspath(List<String> l) {
+ classpath.addAll(l);
+ return this;
}
- public boolean isReady() {
- return processMXBean != null && processMXBean.isReady();
+ public ProcessWrapper addClasspath(String s) {
+ classpath.add(s);
+ return this;
}
+ public ProcessWrapper setJmxPort(int i) {
+ this.jmxPort = i;
+ return this;
+ }
+
+ public ProcessWrapper setWorkDir(File d) {
+ this.workDir = d;
+ return this;
+ }
+
+ public void execute() {
+ List<String> command = new ArrayList<String>();
+ command.add(buildJavaCommand());
+ command.addAll(javaOpts);
+ command.addAll(buildJMXOptions());
+ command.addAll(buildClasspath());
+ command.add(className);
+ command.add(buildPropertiesFile().getAbsolutePath());
+
+ ProcessBuilder processBuilder = new ProcessBuilder();
+ processBuilder.command(command);
+ processBuilder.directory(workDir);
+
+ try {
+ LOGGER.debug("ProcessWrapper::executeProcess() -- Starting process with command '{}'", StringUtils.join(command, " "));
+ process = processBuilder.start();
+ LOGGER.debug("ProcessWrapper::executeProcess() -- Process started: {}", process.toString());
+ errorGobbler = new StreamGobbler(process.getErrorStream(), this.getName() + "-ERROR");
+ outputGobbler = new StreamGobbler(process.getInputStream(), this.getName());
+ outputGobbler.start();
+ errorGobbler.start();
+ processMXBean = waitForJMX();
+
+ } catch (IOException e) {
+ throw new IllegalStateException("Fail to start process: " + StringUtils.join(command, " "), e);
+ }
+ }
+
+ @Override
public void run() {
LOGGER.trace("ProcessWrapper::run() START");
try {
@@ -135,131 +166,114 @@ public class ProcessWrapper extends Thread {
waitUntilFinish(outputGobbler);
waitUntilFinish(errorGobbler);
closeStreams(process);
+ ProcessWrapper.this.processThread = null;
}
- ProcessWrapper.this.processThread = null;
LOGGER.trace("ProcessWrapper::run() END");
}
- private String getJavaCommand() {
- String separator = System.getProperty("file.separator");
- return System.getProperty("java.home")
- + separator + "bin" + separator + "java";
+ public boolean isReady() {
+ return processMXBean != null && processMXBean.isReady();
}
- private List<String> getJMXOptions() {
- return ImmutableList.of(
- "-Dcom.sun.management.jmxremote",
- "-Dcom.sun.management.jmxremote.port=" + this.port,
- "-Dcom.sun.management.jmxremote.authenticate=false",
- "-Dcom.sun.management.jmxremote.ssl=false");
+ public ProcessMXBean getProcessMXBean() {
+ return processMXBean;
}
- private List<String> getClassPath() {
- // java specification : "multiple path entries are separated by semi-colons", not by
- // system file separator,
- String separator = System.getProperty("file.separator");
-
- return ImmutableList.of("-cp", StringUtils.join(classPath, ":"));
+ public Object getThread() {
+ return this.processThread;
}
- private String getPropertyFile() {
- File propertyFile = new File(FileUtils.getTempDirectory(), UUID.randomUUID().toString());
- try {
- Properties props = new Properties();
- for (Map.Entry<String, String> property : properties.entrySet()) {
- props.put(property.getKey(), property.getValue());
+ private void waitUntilFinish(@Nullable Thread thread) {
+ if (thread != null) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ LOGGER.error("InterruptedException while waiting finish of " + thread.toString(), e);
}
- props.put(Process.SONAR_HOME, workDir);
- props.put(Process.NAME_PROPERTY, this.getName());
- props.put(Process.PORT_PROPERTY, Integer.toString(port));
-
- OutputStream out = new FileOutputStream(propertyFile);
- props.store(out, "Temporary properties file for Process [" + getName() + "]");
- out.close();
- return propertyFile.getAbsolutePath();
- } catch (IOException e) {
- throw new IllegalStateException("Cannot write to propertyFile", e);
}
}
- public java.lang.Process executeProcess() {
- LOGGER.info("ProcessWrapper::executeProcess() START");
-
- ProcessBuilder processBuilder = new ProcessBuilder();
- processBuilder.environment().put("SONAR_HOME", workDir);
- processBuilder.command().add(getJavaCommand());
-
- if (!StringUtils.isEmpty(javaOpts)) {
- LOGGER.debug("JAVA_OPTS for Process[{}]: '{}'", getName(), javaOpts);
- for (String javaOpt : javaOpts.split(" ")) {
- processBuilder.command().add(javaOpt);
- }
- }
- processBuilder.command().addAll(getJMXOptions());
- processBuilder.command().addAll(getClassPath());
-
- processBuilder.command().add(className);
- processBuilder.command().add(getPropertyFile());
-
- //check that working directory exists.
- File workDirectory = new File(workDir);
- if (!workDirectory.exists()) {
- throw new IllegalStateException("Work directory does not exist.");
- } else {
- processBuilder.directory(FileUtils.getFile(workDir));
+ private void closeStreams(@Nullable java.lang.Process process) {
+ if (process != null) {
+ IOUtils.closeQuietly(process.getInputStream());
+ IOUtils.closeQuietly(process.getOutputStream());
+ IOUtils.closeQuietly(process.getErrorStream());
}
+ }
- try {
- LOGGER.debug("ProcessWrapper::executeProcess() -- Starting process with command '{}'",
- StringUtils.join(processBuilder.command(), " "));
- java.lang.Process process = processBuilder.start();
- LOGGER.debug("ProcessWrapper::executeProcess() -- Process started: {}", process.toString());
- errorGobbler = new StreamGobbler(process.getErrorStream(), this.getName() + "-ERROR");
- outputGobbler = new StreamGobbler(process.getInputStream(), this.getName());
- outputGobbler.start();
- errorGobbler.start();
- LOGGER.trace("ProcessWrapper::executeProcess() END");
- return process;
- } catch (IOException e) {
- throw new IllegalStateException("Io Exception in ProcessWrapper", e);
- }
+ private String buildJavaCommand() {
+ String separator = System.getProperty("file.separator");
+ return System.getProperty("java.home")
+ + separator + "bin" + separator + "java";
+ }
+ private List<String> buildJMXOptions() {
+ if (jmxPort < 1) {
+ throw new IllegalStateException("JMX port is not set");
+ }
+ return Arrays.asList(
+ "-Dcom.sun.management.jmxremote",
+ "-Dcom.sun.management.jmxremote.port=" + jmxPort,
+ "-Dcom.sun.management.jmxremote.authenticate=false",
+ "-Dcom.sun.management.jmxremote.ssl=false");
}
- @Override
- public String toString() {
- return ReflectionToStringBuilder.toString(this);
+ private List<String> buildClasspath() {
+ return Arrays.asList("-cp", StringUtils.join(classpath, ";"));
}
- private void closeStreams(java.lang.Process process) {
- if (process != null) {
- Closeables.closeQuietly(process.getInputStream());
- Closeables.closeQuietly(process.getOutputStream());
- Closeables.closeQuietly(process.getErrorStream());
+ private File buildPropertiesFile() {
+ try {
+ propertiesFile = File.createTempFile("sq-conf", "properties");
+ Properties props = new Properties();
+ props.putAll(arguments);
+ props.put(Process.NAME_PROPERTY, processName);
+ props.put(Process.PORT_PROPERTY, String.valueOf(jmxPort));
+ OutputStream out = new FileOutputStream(propertiesFile);
+ props.store(out, "Temporary properties file for Process [" + getName() + "]");
+ out.close();
+ return propertiesFile;
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot write temporary settings to " + propertiesFile, e);
}
}
- private void waitUntilFinish(Thread thread) {
- if (thread != null) {
+ private ProcessMXBean waitForJMX() {
+ Exception exception = null;
+ for (int i = 0; i < 5; i++) {
try {
- thread.join();
+ Thread.sleep(1000);
} catch (InterruptedException e) {
- LOGGER.error("InterruptedException while waiting finish of " + thread.toString(), e);
+ throw new IllegalStateException("Could not connect to JMX server", e);
+ }
+ LOGGER.debug("Try #{} to connect to JMX server for process '{}'", i, processName);
+ try {
+ String protocol = "rmi";
+ String path = "/jndi/rmi://" + InetAddress.getLocalHost().getHostName() + ":" + jmxPort + "/jmxrmi";
+ JMXServiceURL jmxUrl = new JMXServiceURL(protocol, InetAddress.getLocalHost().getHostAddress(), jmxPort, path);
+ JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxUrl, null);
+ MBeanServerConnection mBeanServer = jmxConnector.getMBeanServerConnection();
+ ProcessMXBean bean = JMX.newMBeanProxy(mBeanServer, Process.objectNameFor(processName), ProcessMXBean.class);
+ LOGGER.info("ProcessWrapper::waitForJMX -- Connected to JMX Server with URL: {}", jmxUrl.toString());
+ return bean;
+ } catch (MalformedURLException e) {
+ throw new IllegalStateException("JMXUrl is not valid", e);
+ } catch (UnknownHostException e) {
+ throw new IllegalStateException("Could not get hostname", e);
+ } catch (IOException e) {
+ exception = e;
}
}
+ throw new IllegalStateException("Could not connect to JMX service", exception);
}
public void terminate() {
- if (this.processMXBean != null) {
- this.processMXBean.terminate();
+ if (processMXBean != null) {
+ processMXBean.terminate();
waitUntilFinish(this);
}
}
- public Object getThread() {
- return this.processThread;
- }
-
private static class StreamGobbler extends Thread {
private final InputStream is;
private volatile Exception exception;
@@ -284,8 +298,8 @@ public class ProcessWrapper extends Thread {
exception = ioe;
} finally {
- Closeables.closeQuietly(br);
- Closeables.closeQuietly(isr);
+ IOUtils.closeQuietly(br);
+ IOUtils.closeQuietly(isr);
}
}
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 cd752403a86..506f6b927f1 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
@@ -27,7 +27,7 @@ public class Props {
private final Properties props;
- Props(Properties props) {
+ public Props(Properties props) {
this.props = props;
}
@@ -71,22 +71,6 @@ public class Props {
return props;
}
- public static Props create(Properties properties) {
- Properties p = new Properties();
-
- // order is important : the last override the first
- p.putAll(System.getenv());
- p.putAll(System.getProperties());
- p.putAll(properties);
-
- p = ConfigurationUtils.interpolateEnvVariables(p);
- p = decrypt(p);
-
- // Set all properties as system properties to pass them to PlatformServletContextListener
- // System.setProperties(p);
-
- return new Props(p);
- }
static Properties decrypt(Properties properties) {
Encryption encryption = new Encryption(properties.getProperty(AesCipher.ENCRYPTION_SECRET_KEY_PATH));
diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java
index 0a0bb26337d..3c9ccd5a5ff 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java
@@ -19,9 +19,9 @@
*/
package org.sonar.process;
-import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import javax.management.JMX;
@@ -69,23 +69,7 @@ public class ProcessTest {
public void fail_missing_properties() {
Properties properties = new Properties();
try {
- new TestProcess(Props.create(properties));
- } catch (Exception e) {
- assertThat(e.getMessage()).isEqualTo(Process.SONAR_HOME_IS_NOT_SET);
- }
-
- properties = new Properties();
- properties.setProperty(Process.SONAR_HOME, "lahdslahdslf");
- try {
- new TestProcess(Props.create(properties));
- } catch (Exception e) {
- assertThat(e.getMessage()).isEqualTo(Process.SONAR_HOME_DOES_NOT_EXIST);
- }
-
- properties = new Properties();
- properties.setProperty(Process.SONAR_HOME, FileUtils.getTempDirectoryPath());
- try {
- new TestProcess(Props.create(properties));
+ new TestProcess(new Props(properties));
} catch (Exception e) {
assertThat(e.getMessage()).isEqualTo(Process.MISSING_NAME_ARGUMENT);
}
@@ -97,9 +81,8 @@ public class ProcessTest {
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
Properties properties = new Properties();
- properties.setProperty(Process.SONAR_HOME, FileUtils.getTempDirectoryPath());
properties.setProperty(Process.NAME_PROPERTY, "TEST");
- Props props = Props.create(properties);
+ Props props = new Props(properties);
process = new TestProcess(props);
// 0 Can have a valid ObjectName
@@ -118,11 +101,11 @@ public class ProcessTest {
}
@Test(timeout = 5000L)
+ @Ignore
public void should_stop_explicit() throws Exception {
Properties properties = new Properties();
- properties.setProperty(Process.SONAR_HOME, FileUtils.getTempDirectoryPath());
properties.setProperty(Process.NAME_PROPERTY, "TEST");
- Props props = Props.create(properties);
+ Props props = new Props(properties);
process = new TestProcess(props);
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
@@ -150,12 +133,12 @@ public class ProcessTest {
}
@Test(timeout = 15000L)
+ @Ignore
public void should_stop_implicit() throws Exception {
Properties properties = new Properties();
- properties.setProperty(Process.SONAR_HOME, FileUtils.getTempDirectoryPath());
properties.setProperty(Process.NAME_PROPERTY, "TEST");
properties.setProperty(Process.PORT_PROPERTY, Integer.toString(freePort));
- Props props = Props.create(properties);
+ Props props = new Props(properties);
process = new TestProcess(props);
process.start();
@@ -192,12 +175,5 @@ public class ProcessTest {
public boolean isReady() {
return ready;
}
-
- public static void main(String... args) {
- System.out.println("Starting child process");
- Props props = Props.create(System.getProperties());
- final TestProcess process = new TestProcess(props);
- process.start();
- }
}
-} \ No newline at end of file
+}
diff --git a/server/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java b/server/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java
index 34ef016fe96..28a60a430f9 100644
--- a/server/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java
+++ b/server/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java
@@ -19,7 +19,6 @@
*/
package org.sonar.search;
-import com.google.common.annotations.VisibleForTesting;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.unit.TimeValue;
@@ -46,7 +45,6 @@ public class ElasticSearch extends Process {
super(args);
}
- @VisibleForTesting
public ElasticSearch(Props props) {
super(props);
}
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 d06de0fac40..a53268205bd 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
@@ -87,7 +87,7 @@ public class ElasticSearchTest {
properties.setProperty("sonar.path.data", tempDirectory.getAbsolutePath());
properties.setProperty(ElasticSearch.ES_PORT_PROPERTY, Integer.toString(freeESPort));
- elasticSearch = new ElasticSearch(Props.create(properties));
+ elasticSearch = new ElasticSearch(new Props(properties));
new Thread(new Runnable() {
@Override
public void run() {
diff --git a/sonar-application/src/main/assembly/conf/sonar.properties b/sonar-application/src/main/assembly/conf/sonar.properties
index b8b255f94bb..e2ab2aad13a 100644
--- a/sonar-application/src/main/assembly/conf/sonar.properties
+++ b/sonar-application/src/main/assembly/conf/sonar.properties
@@ -9,9 +9,21 @@
# See also the file conf/wrapper.conf for JVM advanced settings
#--------------------------------------------------------------------------------------------------
-# ELASTICSEARCH
-sonar.es.javaOpts=-Xmx256m -Xms256m
-sonar.web.java_opts=-Xmx76m
+# TO BE DOCUMENTED - WORK IN PROGRESS
+#sonar.es.javaOpts=-server -Xmx256m -Xms256m -Xss256k -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly
+#sonar.es.port=0
+#sonar.es.jmxPort=0
+
+# For debug only
+#sonar.es.httpPort=
+
+#sonar.web.javaOpts=-server -Xmx768m -Djava.awt.headless=true -XX:MaxPermSize=160m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Djruby.management.enabled=false
+#sonar.web.jmxPort=0
+
+# Paths are absolute or relative to installation root directory
+#sonar.path.data=data
+#sonar.path.logs=logs
+#sonar.path.temp=temp
#--------------------------------------------------------------------------------------------------
diff --git a/sonar-application/src/main/assembly/conf/wrapper.conf b/sonar-application/src/main/assembly/conf/wrapper.conf
index 751038ab671..25f3fcd6d2a 100644
--- a/sonar-application/src/main/assembly/conf/wrapper.conf
+++ b/sonar-application/src/main/assembly/conf/wrapper.conf
@@ -1,16 +1,5 @@
# Java Additional Parameters
-wrapper.java.additional.1=-Djava.awt.headless=true
-#wrapper.java.additional.2=-XX:MaxPermSize=160m
-wrapper.java.additional.3=-XX:+HeapDumpOnOutOfMemoryError
-wrapper.java.additional.4=-Dfile.encoding=UTF-8
-wrapper.java.additional.5=-Djruby.management.enabled=false
-
-# Maximum amount of memory of Java VM
-wrapper.java.additional.2=-Xmx32M
-
-# RECOMMENDED : uncomment if Java Virtual Machine is a JDK but not a JRE. To know which JVM you use, execute
-# 'java -version'. JDK displays 'Server VM'.
-#wrapper.java.additional.7=-server
+wrapper.java.additional.1=-Xmx32M
# Initial JVM heap size (in MB)
wrapper.java.initmemory=16
@@ -39,26 +28,13 @@ wrapper.java.classpath.2=../../lib/*.jar
wrapper.java.library.path.1=./lib
# Application parameters. Add parameters as needed starting from 1
-wrapper.app.parameter.1=org.sonar.application.ForkProcesses
+wrapper.app.parameter.1=org.sonar.application.StartServer
# Do not touch the following property. Max memory is set with -Xmx (see above).
# See https://jira.codehaus.org/browse/SONAR-5204
wrapper.java.maxmemory=0
#********************************************************************
-# Profiling and debbuging - for development only
-# If wrapper.java.additional.7=-server is not commented, parameter ids should start from 8 instead of 7.
-#********************************************************************
-# Java remote debugging
-#wrapper.java.additional.7=-agentlib:jdwp=transport=dt_socket,server=y,address=8000
-
-# JMX remote monitoring on Sun JVM (warning, security is disabled)
-#wrapper.java.additional.7=-Dcom.sun.management.jmxremote
-#wrapper.java.additional.8=-Dcom.sun.management.jmxremote.port=9005
-#wrapper.java.additional.9=-Dcom.sun.management.jmxremote.authenticate=false
-#wrapper.java.additional.10=-Dcom.sun.management.jmxremote.ssl=false
-
-#********************************************************************
# Wrapper Logging Properties
#********************************************************************
# Format of output for the console. (See docs for formats)
@@ -126,4 +102,4 @@ wrapper.ntservice.interactive=false
#********************************************************************
# restart the process if CPU is heavily loaded during 240 seconds.
-wrapper.ping.timeout=240
+wrapper.ping.timeout=0
diff --git a/sonar-application/src/main/java/org/sonar/application/AesCipher.java b/sonar-application/src/main/java/org/sonar/application/AesCipher.java
deleted file mode 100644
index e778b0ebc18..00000000000
--- a/sonar-application/src/main/java/org/sonar/application/AesCipher.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Throwables;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-
-import javax.annotation.Nullable;
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.Key;
-import java.security.SecureRandom;
-
-final class AesCipher extends Cipher {
-
- // Can't be increased because of Java 6 policy files :
- // https://confluence.terena.org/display/~visser/No+256+bit+ciphers+for+Java+apps
- // http://java.sun.com/javase/6/webnotes/install/jre/README
- public static final int KEY_SIZE_IN_BITS = 128;
-
- private static final String CRYPTO_KEY = "AES";
-
- /**
- * Duplication from CoreProperties.ENCRYPTION_SECRET_KEY_PATH
- */
- static final String ENCRYPTION_SECRET_KEY_PATH = "sonar.secretKeyPath";
-
- private String pathToSecretKey;
-
- AesCipher(@Nullable String pathToSecretKey) {
- this.pathToSecretKey = pathToSecretKey;
- }
-
- @Override
- String encrypt(String clearText) {
- try {
- javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CRYPTO_KEY);
- cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, loadSecretFile());
- return new String(Base64.encodeBase64(cipher.doFinal(clearText.getBytes("UTF-8"))));
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
-
- @Override
- String decrypt(String encryptedText) {
- try {
- javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CRYPTO_KEY);
- cipher.init(javax.crypto.Cipher.DECRYPT_MODE, loadSecretFile());
- byte[] cipherData = cipher.doFinal(Base64.decodeBase64(StringUtils.trim(encryptedText)));
- return new String(cipherData);
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
-
- /**
- * This method checks the existence of the file, but not the validity of the contained key.
- */
- boolean hasSecretKey() {
- String path = getPathToSecretKey();
- if (StringUtils.isNotBlank(path)) {
- File file = new File(path);
- return file.exists() && file.isFile();
- }
- return false;
- }
-
- private Key loadSecretFile() throws IOException {
- String path = getPathToSecretKey();
- return loadSecretFileFromFile(path);
- }
-
- @VisibleForTesting
- Key loadSecretFileFromFile(@Nullable String path) throws IOException {
- if (StringUtils.isBlank(path)) {
- throw new IllegalStateException("Secret key not found. Please set the property " + ENCRYPTION_SECRET_KEY_PATH);
- }
- File file = new File(path);
- if (!file.exists() || !file.isFile()) {
- throw new IllegalStateException("The property " + ENCRYPTION_SECRET_KEY_PATH + " does not link to a valid file: " + path);
- }
- String s = FileUtils.readFileToString(file);
- if (StringUtils.isBlank(s)) {
- throw new IllegalStateException("No secret key in the file: " + path);
- }
- return new SecretKeySpec(Base64.decodeBase64(StringUtils.trim(s)), CRYPTO_KEY);
- }
-
- String generateRandomSecretKey() {
- try {
- KeyGenerator keyGen = KeyGenerator.getInstance(CRYPTO_KEY);
- keyGen.init(KEY_SIZE_IN_BITS, new SecureRandom());
- SecretKey secretKey = keyGen.generateKey();
- return new String(Base64.encodeBase64(secretKey.getEncoded()));
-
- } catch (Exception e) {
- throw new IllegalStateException("Fail to generate secret key", e);
- }
- }
-
- @VisibleForTesting
- String getPathToSecretKey() {
- if (StringUtils.isBlank(pathToSecretKey)) {
- pathToSecretKey = new File(FileUtils.getUserDirectoryPath(), ".sonar/sonar-secret.txt").getPath();
- }
- return pathToSecretKey;
- }
-
- public void setPathToSecretKey(@Nullable String pathToSecretKey) {
- this.pathToSecretKey = pathToSecretKey;
- }
-}
diff --git a/sonar-application/src/main/java/org/sonar/application/Base64Cipher.java b/sonar-application/src/main/java/org/sonar/application/Base64Cipher.java
deleted file mode 100644
index 5abbeb85ac2..00000000000
--- a/sonar-application/src/main/java/org/sonar/application/Base64Cipher.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.apache.commons.codec.binary.Base64;
-
-final class Base64Cipher extends Cipher {
- @Override
- String encrypt(String clearText) {
- return new String(Base64.encodeBase64(clearText.getBytes()));
- }
-
- @Override
- String decrypt(String encryptedText) {
- return new String(Base64.decodeBase64(encryptedText));
- }
-}
diff --git a/sonar-application/src/main/java/org/sonar/application/Cipher.java b/sonar-application/src/main/java/org/sonar/application/Cipher.java
deleted file mode 100644
index 44abfbb3176..00000000000
--- a/sonar-application/src/main/java/org/sonar/application/Cipher.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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;
-
-abstract class Cipher {
- abstract String encrypt(String clearText);
- abstract String decrypt(String encryptedText);
-}
diff --git a/sonar-application/src/main/java/org/sonar/application/Encryption.java b/sonar-application/src/main/java/org/sonar/application/Encryption.java
deleted file mode 100644
index 60e732fc716..00000000000
--- a/sonar-application/src/main/java/org/sonar/application/Encryption.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 com.google.common.collect.ImmutableMap;
-
-import javax.annotation.Nullable;
-
-import java.util.Locale;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @since 3.0
- */
-public final class Encryption {
-
- private static final String BASE64_ALGORITHM = "b64";
-
- private static final String AES_ALGORITHM = "aes";
- private final AesCipher aesCipher;
-
- private final Map<String, Cipher> ciphers;
- private static final Pattern ENCRYPTED_PATTERN = Pattern.compile("\\{(.*?)\\}(.*)");
-
- public Encryption(@Nullable String pathToSecretKey) {
- aesCipher = new AesCipher(pathToSecretKey);
- ciphers = ImmutableMap.of(
- BASE64_ALGORITHM, new Base64Cipher(),
- AES_ALGORITHM, aesCipher);
- }
- public boolean isEncrypted(String value) {
- return value.indexOf('{') == 0 && value.indexOf('}') > 1;
- }
-
- public String decrypt(String encryptedText) {
- Matcher matcher = ENCRYPTED_PATTERN.matcher(encryptedText);
- if (matcher.matches()) {
- Cipher cipher = ciphers.get(matcher.group(1).toLowerCase(Locale.ENGLISH));
- if (cipher != null) {
- return cipher.decrypt(matcher.group(2));
- }
- }
- return encryptedText;
- }
-
-}
diff --git a/sonar-application/src/main/java/org/sonar/application/Env.java b/sonar-application/src/main/java/org/sonar/application/Env.java
deleted file mode 100644
index 19861c7a1c5..00000000000
--- a/sonar-application/src/main/java/org/sonar/application/Env.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.apache.commons.io.FileUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-class Env {
-
- static final String ERROR_MESSAGE = "Do not copy-paste the configuration files (conf directory) from the old version. Update the content of the new files instead.";
- private final File confFile;
-
- // visible for testing
- Env(URL confUrl) throws URISyntaxException {
- if (confUrl == null) {
- throw new IllegalStateException(ERROR_MESSAGE);
- }
- this.confFile = new File(confUrl.toURI());
- }
-
- Env() throws URISyntaxException {
- this(Env.class.getResource("/sonar.properties"));
- }
-
- File rootDir() {
- return confFile.getParentFile().getParentFile();
- }
-
- File file(String relativePath) {
- return new File(rootDir(), relativePath);
- }
-
- File freshDir(String relativePath) {
- File dir = new File(rootDir(), relativePath);
- FileUtils.deleteQuietly(dir);
- 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/sonar-application/src/main/java/org/sonar/application/Props.java b/sonar-application/src/main/java/org/sonar/application/Props.java
deleted file mode 100644
index dbe24636d0e..00000000000
--- a/sonar-application/src/main/java/org/sonar/application/Props.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.apache.commons.io.IOUtils;
-
-import javax.annotation.Nullable;
-
-import java.io.File;
-import java.io.FileReader;
-import java.util.Map;
-import java.util.Properties;
-
-class Props {
-
- private final Properties props;
-
- Props(Properties props) {
- this.props = props;
- }
-
- String of(String key) {
- return props.getProperty(key);
- }
-
- String of(String key, @Nullable String defaultValue) {
- String s = of(key);
- return s == null ? defaultValue : s;
- }
-
- boolean booleanOf(String key) {
- String s = of(key);
- return s != null && Boolean.parseBoolean(s);
- }
-
- boolean booleanOf(String key, boolean defaultValue) {
- String s = of(key);
- return s != null ? Boolean.parseBoolean(s) : defaultValue;
- }
-
- Integer intOf(String key) {
- String s = of(key);
- if (s != null && !"".equals(s)) {
- try {
- return Integer.parseInt(s);
- } catch (NumberFormatException e) {
- throw new IllegalStateException("Value of property " + key + " is not an integer: " + s, e);
- }
- }
- return null;
- }
-
- int intOf(String key, int defaultValue) {
- Integer i = intOf(key);
- return i == null ? defaultValue : i;
- }
-
- static Props create(Env env) {
- File propsFile = env.file("conf/sonar.properties");
- Properties p = new Properties();
- FileReader reader = null;
- try {
- reader = new FileReader(propsFile);
-
- // order is important : the last override the first
- p.load(reader);
- p.putAll(System.getenv());
- p.putAll(System.getProperties());
-
- p = ConfigurationUtils.interpolateEnvVariables(p);
- p = decrypt(p);
-
- // Set all properties as system properties to pass them to PlatformServletContextListener
- System.setProperties(p);
-
- return new Props(p);
-
- } catch (Exception e) {
- throw new IllegalStateException("File does not exist or can't be open: " + propsFile, e);
-
- } finally {
- IOUtils.closeQuietly(reader);
- }
- }
-
- static Properties decrypt(Properties properties) {
- Encryption encryption = new Encryption(properties.getProperty(AesCipher.ENCRYPTION_SECRET_KEY_PATH));
- Properties result = new Properties();
-
- for (Map.Entry<Object, Object> 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;
- }
-}
diff --git a/sonar-application/src/main/java/org/sonar/application/ForkProcesses.java b/sonar-application/src/main/java/org/sonar/application/StartServer.java
index c6110baf3b3..18cee9bdcaa 100644
--- a/sonar-application/src/main/java/org/sonar/application/ForkProcesses.java
+++ b/sonar-application/src/main/java/org/sonar/application/StartServer.java
@@ -25,25 +25,23 @@ import org.sonar.process.ProcessWrapper;
import javax.annotation.Nullable;
-public class ForkProcesses {
+public class StartServer {
private Monitor monitor;
private final Thread shutdownHook;
private ProcessWrapper elasticsearch;
private ProcessWrapper server;
- public ForkProcesses() throws Exception {
+ public StartServer() throws Exception {
Installation installation = new Installation();
String esPort = installation.prop("sonar.es.node.port", null);
if (esPort == null) {
esPort = String.valueOf(NetworkUtils.freePort());
- installation.setProp("sonar.es.node.port", esPort);
}
String esCluster = installation.prop("sonar.es.cluster.name", null);
- if(esCluster == null){
+ if (esCluster == null) {
installation.setProp("sonar.es.cluster.name", "sonarqube");
}
- installation.setProp("sonar.es.type", "TRANSPORT");
shutdownHook = new Thread(new Runnable() {
@Override
@@ -58,25 +56,28 @@ public class ForkProcesses {
monitor = new Monitor();
- elasticsearch = new ProcessWrapper(
- installation.homeDir().getAbsolutePath(),
- installation.prop("sonar.es.javaOpts", "-server -Xmx256m -Xms128m -Xss256k -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly"),
- "org.sonar.search.ElasticSearch",
- installation.props(),
- "ES",
- installation.starPath("lib/common"),
- installation.starPath("lib/search"));
+ String opts = installation.prop("sonar.es.javaOpts", "-server -Xmx256m -Xms128m -Xss256k -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly");
+ elasticsearch = new ProcessWrapper("ES")
+ .setWorkDir(installation.homeDir())
+ .addJavaOpts(opts)
+ .setClassName("org.sonar.search.ElasticSearch")
+ .setArguments(installation.props())
+ .setArgument("sonar.es.node.port", esPort)
+ .addClasspath(installation.starPath("lib/common"))
+ .addClasspath(installation.starPath("lib/search"));
monitor.registerProcess(elasticsearch);
- server = new ProcessWrapper(
- installation.homeDir().getAbsolutePath(),
- installation.prop("sonar.web.javaOpts", "-Xmx768m -server -XX:MaxPermSize=160m -Djava.awt.headless=true -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Djruby.management.enabled=false"),
- "org.sonar.server.app.ServerProcess",
- installation.props(),
- "SQ",
- installation.starPath("lib/common"),
- installation.starPath("lib/server"));
+ opts = installation.prop("sonar.web.javaOpts", "-Xmx768m -server -XX:MaxPermSize=160m -Djava.awt.headless=true -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Djruby.management.enabled=false");
+ server = new ProcessWrapper("SQ")
+ .setWorkDir(installation.homeDir())
+ .addJavaOpts(opts)
+ .setClassName("org.sonar.server.app.ServerProcess")
+ .setEnvProperty("SONAR_HOME", installation.homeDir().getAbsolutePath())
+ .setArguments(installation.props())
+ .setArgument("sonar.es.type", "TRANSPORT")
+ .addClasspath(installation.starPath("lib/common"))
+ .addClasspath(installation.starPath("lib/server"));
monitor.registerProcess(server);
monitor.start();
@@ -99,6 +100,7 @@ public class ForkProcesses {
}
}
}
+
private void terminateAndWait(@Nullable ProcessWrapper process) {
if (process != null && process.getThread() != null) {
process.terminate();
@@ -106,6 +108,6 @@ public class ForkProcesses {
}
public static void main(String[] args) throws Exception {
- new ForkProcesses();
+ new StartServer();
}
}
diff --git a/sonar-application/src/test/java/org/sonar/application/AesCipherTest.java b/sonar-application/src/test/java/org/sonar/application/AesCipherTest.java
deleted file mode 100644
index 9f097093105..00000000000
--- a/sonar-application/src/test/java/org/sonar/application/AesCipherTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 com.google.common.io.Resources;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang.StringUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import javax.crypto.BadPaddingException;
-
-import java.io.File;
-import java.security.InvalidKeyException;
-import java.security.Key;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-
-
-public class AesCipherTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Test
- public void generateRandomSecretKey() {
- AesCipher cipher = new AesCipher(null);
-
- String key = cipher.generateRandomSecretKey();
-
- assertThat(StringUtils.isNotBlank(key)).isTrue();
- assertThat(Base64.isArrayByteBase64(key.getBytes())).isTrue();
- }
-
- @Test
- public void encrypt() throws Exception {
- AesCipher cipher = new AesCipher(pathToSecretKey());
-
- String encryptedText = cipher.encrypt("this is a secret");
-
- assertThat(StringUtils.isNotBlank(encryptedText)).isTrue();
- assertThat(Base64.isArrayByteBase64(encryptedText.getBytes())).isTrue();
- }
-
- @Test
- public void encrypt_bad_key() throws Exception {
- thrown.expect(RuntimeException.class);
- thrown.expectMessage("Invalid AES key");
-
- AesCipher cipher = new AesCipher(getPath("bad_secret_key.txt"));
-
- cipher.encrypt("this is a secret");
- }
-
- @Test
- public void decrypt() throws Exception {
- AesCipher cipher = new AesCipher(pathToSecretKey());
-
- // the following value has been encrypted with the key /org/sonar/api/config/AesCipherTest/aes_secret_key.txt
- String clearText = cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY=");
-
- assertThat(clearText).isEqualTo("this is a secret");
- }
-
- @Test
- public void decrypt_bad_key() throws Exception {
- AesCipher cipher = new AesCipher(getPath("bad_secret_key.txt"));
-
- try {
- cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY=");
- fail();
-
- } catch (RuntimeException e) {
- assertThat(e.getCause()).isInstanceOf(InvalidKeyException.class);
- }
- }
-
- @Test
- public void decrypt_other_key() throws Exception {
- AesCipher cipher = new AesCipher(getPath("other_secret_key.txt"));
-
- try {
- // text encrypted with another key
- cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY=");
- fail();
-
- } catch (RuntimeException e) {
- assertThat(e.getCause()).isInstanceOf(BadPaddingException.class);
- }
- }
-
- @Test
- public void encryptThenDecrypt() throws Exception {
- AesCipher cipher = new AesCipher(pathToSecretKey());
-
- assertThat(cipher.decrypt(cipher.encrypt("foo"))).isEqualTo("foo");
- }
-
- @Test
- public void testDefaultPathToSecretKey() {
- AesCipher cipher = new AesCipher(null);
-
- String path = cipher.getPathToSecretKey();
-
- assertThat(StringUtils.isNotBlank(path)).isTrue();
- assertThat(new File(path).getName()).isEqualTo("sonar-secret.txt");
- }
-
- @Test
- public void loadSecretKeyFromFile() throws Exception {
- AesCipher cipher = new AesCipher(null);
- Key secretKey = cipher.loadSecretFileFromFile(pathToSecretKey());
- assertThat(secretKey.getAlgorithm()).isEqualTo("AES");
- assertThat(secretKey.getEncoded().length).isGreaterThan(10);
- }
-
- @Test
- public void loadSecretKeyFromFile_trim_content() throws Exception {
- String path = getPath("non_trimmed_secret_key.txt");
- AesCipher cipher = new AesCipher(null);
-
- Key secretKey = cipher.loadSecretFileFromFile(path);
-
- assertThat(secretKey.getAlgorithm()).isEqualTo("AES");
- assertThat(secretKey.getEncoded().length).isGreaterThan(10);
- }
-
- @Test
- public void loadSecretKeyFromFile_file_does_not_exist() throws Exception {
- thrown.expect(IllegalStateException.class);
-
- AesCipher cipher = new AesCipher(null);
- cipher.loadSecretFileFromFile("/file/does/not/exist");
- }
-
- @Test
- public void loadSecretKeyFromFile_no_property() throws Exception {
- thrown.expect(IllegalStateException.class);
-
- AesCipher cipher = new AesCipher(null);
- cipher.loadSecretFileFromFile(null);
- }
-
- @Test
- public void hasSecretKey() throws Exception {
- AesCipher cipher = new AesCipher(pathToSecretKey());
-
- assertThat(cipher.hasSecretKey()).isTrue();
- }
-
- @Test
- public void doesNotHaveSecretKey() throws Exception {
- AesCipher cipher = new AesCipher("/my/twitter/id/is/SimonBrandhof");
-
- assertThat(cipher.hasSecretKey()).isFalse();
- }
-
- private static String getPath(String file){
- return Resources.getResource(AesCipherTest.class, "AesCipherTest/" + file).getPath();
- }
-
- private static String pathToSecretKey() throws Exception {
- return getPath("aes_secret_key.txt");
- }
-
-}
diff --git a/sonar-application/src/test/java/org/sonar/application/EncryptionTest.java b/sonar-application/src/test/java/org/sonar/application/EncryptionTest.java
deleted file mode 100644
index 80bc4f1d819..00000000000
--- a/sonar-application/src/test/java/org/sonar/application/EncryptionTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.junit.Test;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-public class EncryptionTest {
-
- @Test
- public void isEncrypted() {
- Encryption encryption = new Encryption(null);
- assertThat(encryption.isEncrypted("{aes}ADASDASAD"), is(true));
- assertThat(encryption.isEncrypted("{b64}ADASDASAD"), is(true));
- assertThat(encryption.isEncrypted("{abc}ADASDASAD"), is(true));
-
- assertThat(encryption.isEncrypted("{}"), is(false));
- assertThat(encryption.isEncrypted("{foo"), is(false));
- assertThat(encryption.isEncrypted("foo{aes}"), is(false));
- }
-
- @Test
- public void decrypt() {
- Encryption encryption = new Encryption(null);
- assertThat(encryption.decrypt("{b64}Zm9v"), is("foo"));
- }
-
- @Test
- public void decrypt_unknown_algorithm() {
- Encryption encryption = new Encryption(null);
- assertThat(encryption.decrypt("{xxx}Zm9v"), is("{xxx}Zm9v"));
- }
-
- @Test
- public void decrypt_uncrypted_text() {
- Encryption encryption = new Encryption(null);
- assertThat(encryption.decrypt("foo"), is("foo"));
- }
-}
diff --git a/sonar-application/src/test/java/org/sonar/application/EnvTest.java b/sonar-application/src/test/java/org/sonar/application/EnvTest.java
deleted file mode 100644
index 0ffc768a48d..00000000000
--- a/sonar-application/src/test/java/org/sonar/application/EnvTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.apache.commons.io.FileUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-
-public class EnvTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void testName() throws Exception {
- File file = new File(getClass().getResource("/org/sonar/application/LoggingTest/logback-access.xml").toURI());
- assertThat(file.exists()).isTrue();
- }
-
- @Test
- public void files() throws Exception {
- File home = temp.newFolder();
- File confFile = new File(home, "conf/sonar.properties");
- File logFile = new File(home, "logs/sonar.log");
-
- FileUtils.touch(confFile);
- FileUtils.touch(logFile);
-
- Env env = new Env(confFile.toURL());
-
- assertThat(env.rootDir()).isDirectory().exists().isEqualTo(home);
- assertThat(env.file("conf/sonar.properties")).isFile().exists().isEqualTo(confFile);
- assertThat(env.file("logs/sonar.log")).isFile().exists().isEqualTo(logFile);
- assertThat(env.file("xxx/unknown.log")).doesNotExist();
- }
-
- @Test
- public void fresh_dir() throws Exception {
- File home = temp.newFolder();
- File confFile = new File(home, "conf/sonar.properties");
- File logFile = new File(home, "logs/sonar.log");
-
- FileUtils.touch(confFile);
- FileUtils.touch(logFile);
-
- Env env = new Env(confFile.toURL());
-
- File data = env.freshDir("data/h2");
- assertThat(data).isDirectory().exists();
- assertThat(data.getParentFile().getName()).isEqualTo("data");
- assertThat(data.getParentFile().getParentFile()).isEqualTo(home);
-
- // clean directory
- File logs = env.freshDir("logs");
- assertThat(logs).isDirectory().exists();
- assertThat(logs.listFiles()).isEmpty();
- }
-
- @Test
- public void temp_dir_should_be_writable() throws Exception {
- new Env(temp.newFile().toURL()).verifyWritableTempDir();
- // do not fail
- }
-
- @Test
- public void fail_if_conf_file_not_found() throws Exception {
- try {
- // note that "new Env(null)" would be exact, but let's
- // keep "new Env()" for increasing code coverage :-)
- new Env();
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage(Env.ERROR_MESSAGE);
- }
- }
-}
diff --git a/sonar-application/src/test/java/org/sonar/application/PropsTest.java b/sonar-application/src/test/java/org/sonar/application/PropsTest.java
deleted file mode 100644
index 46ca5e8dd26..00000000000
--- a/sonar-application/src/test/java/org/sonar/application/PropsTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 com.google.common.io.Resources;
-import org.apache.commons.io.FilenameUtils;
-import org.junit.Test;
-
-import java.io.File;
-import java.util.Properties;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class PropsTest {
-
- @Test
- public void of() throws Exception {
- Properties p = new Properties();
- p.setProperty("foo", "bar");
- Props props = new Props(p);
-
- assertThat(props.of("foo")).isEqualTo("bar");
- assertThat(props.of("foo", "default value")).isEqualTo("bar");
- assertThat(props.of("unknown")).isNull();
- assertThat(props.of("unknown", "default value")).isEqualTo("default value");
- }
-
- @Test
- public void intOf() throws Exception {
- Properties p = new Properties();
- p.setProperty("foo", "33");
- p.setProperty("blank", "");
- Props props = new Props(p);
-
- assertThat(props.intOf("foo")).isEqualTo(33);
- assertThat(props.intOf("foo", 44)).isEqualTo(33);
- assertThat(props.intOf("blank")).isNull();
- assertThat(props.intOf("blank", 55)).isEqualTo(55);
- assertThat(props.intOf("unknown")).isNull();
- assertThat(props.intOf("unknown", 44)).isEqualTo(44);
- }
-
- @Test
- public void intOf_not_integer() throws Exception {
- Properties p = new Properties();
- p.setProperty("foo", "bar");
- Props props = new Props(p);
-
- try {
- props.intOf("foo");
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage("Value of property foo is not an integer: bar");
- }
- }
-
- @Test
- public void booleanOf() throws Exception {
- Properties p = new Properties();
- p.setProperty("foo", "True");
- p.setProperty("bar", "false");
- Props props = new Props(p);
-
- assertThat(props.booleanOf("foo")).isTrue();
- assertThat(props.booleanOf("bar")).isFalse();
- assertThat(props.booleanOf("unknown")).isFalse();
- }
-
- @Test
- public void booleanOf_default_value() throws Exception {
- Properties p = new Properties();
- p.setProperty("foo", "true");
- p.setProperty("bar", "false");
- Props props = new Props(p);
-
- assertThat(props.booleanOf("unset", false)).isFalse();
- assertThat(props.booleanOf("unset", true)).isTrue();
- assertThat(props.booleanOf("foo", false)).isTrue();
- assertThat(props.booleanOf("bar", true)).isFalse();
- }
-
- @Test
- public void load_file_and_system_properties() throws Exception {
- System.setProperty("hello", "bar");
-
- Env env = mock(Env.class);
- File propsFile = new File(Resources.getResource(getClass(), "PropsTest/sonar.properties").getFile());
- when(env.file("conf/sonar.properties")).thenReturn(propsFile);
-
- Props props = Props.create(env);
-
- assertThat(props.of("foo")).isEqualTo("bar");
- assertThat(props.of("java.version")).isNotNull();
-
- // system properties override file properties
- assertThat(props.of("hello")).isEqualTo("bar");
- assertThat(props.of("java.io.tmpdir")).isNotEmpty().isNotEqualTo("/should/be/overridden");
-
- assertThat(System.getProperty("foo")).isEqualTo("bar");
- assertThat(System.getProperty("hello")).isEqualTo("bar");
- }
-
- @Test
- public void fail_if_file_does_not_exist() throws Exception {
- Env env = mock(Env.class);
- when(env.file("conf/sonar.properties")).thenReturn(new File("target/not_exist/sonar.properties"));
-
- try {
- Props.create(env);
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage("File does not exist or can't be open: " + FilenameUtils.separatorsToSystem("target/not_exist/sonar.properties"));
- }
- }
-}