diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-07-22 17:59:49 +0200 |
---|---|---|
committer | Stephane Gamard <stephane.gamard@searchbox.com> | 2014-07-23 15:34:05 +0200 |
commit | 1fd258f12f256aea2359d3469f9e6308608485f2 (patch) | |
tree | e6e58dbabead55b15cbd1e1b247c177932556498 /sonar-application | |
parent | 74102a370cf912472957b896ce2141bab76b9535 (diff) | |
download | sonarqube-1fd258f12f256aea2359d3469f9e6308608485f2.tar.gz sonarqube-1fd258f12f256aea2359d3469f9e6308608485f2.zip |
SONAR-4898 some refactoring
Diffstat (limited to 'sonar-application')
13 files changed, 42 insertions, 988 deletions
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")); - } - } -} |