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 final Map<String, String> properties = new HashMap<String, String>();
private File workDir;
private File propertiesFile;
private java.lang.Process process;
return this;
}
- public ProcessWrapper setArgument(String key, String value) {
- arguments.put(key, value);
+ public ProcessWrapper setProperty(String key, String value) {
+ properties.put(key, value);
return this;
}
- public ProcessWrapper setArguments(Map<String, String> args) {
- arguments.clear();
- arguments.putAll(args);
+ public ProcessWrapper setProperties(Map<String, String> args) {
+ properties.clear();
+ properties.putAll(args);
return this;
}
return this;
}
- public void execute() {
+ public ProcessWrapper execute() {
List<String> command = new ArrayList<String>();
command.add(buildJavaCommand());
command.addAll(javaOpts);
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(command);
processBuilder.directory(workDir);
+ processBuilder.environment().putAll(envProperties);
try {
LOGGER.debug("ProcessWrapper::executeProcess() -- Starting process with command '{}'", StringUtils.join(command, " "));
outputGobbler.start();
errorGobbler.start();
processMXBean = waitForJMX();
+ return this;
} catch (IOException e) {
throw new IllegalStateException("Fail to start process: " + StringUtils.join(command, " "), e);
}
private List<String> buildClasspath() {
- return Arrays.asList("-cp", StringUtils.join(classpath, ";"));
+ return Arrays.asList("-cp", StringUtils.join(classpath, System.getProperty("path.separator")));
}
private File buildPropertiesFile() {
try {
propertiesFile = File.createTempFile("sq-conf", "properties");
Properties props = new Properties();
- props.putAll(arguments);
+ props.putAll(properties);
props.put(Process.NAME_PROPERTY, processName);
props.put(Process.PORT_PROPERTY, String.valueOf(jmxPort));
OutputStream out = new FileOutputStream(propertiesFile);
public class ElasticSearch extends Process {
public static final String ES_DEBUG_PROPERTY = "esDebug";
- public static final String ES_PORT_PROPERTY = "sonar.es.node.port";
+ public static final String ES_PORT_PROPERTY = "sonar.es.port";
public static final String ES_CLUSTER_PROPERTY = "sonar.es.cluster.name";
- public static final String DEFAULT_CLUSTER_NAME = "sonarqube";
-
private Node node;
public ElasticSearch(String... args) {
public void onStart() {
String dataDir = props.of("sonar.path.data");
Integer port = props.intOf(ES_PORT_PROPERTY);
- String clusterName = props.of(ES_CLUSTER_PROPERTY, DEFAULT_CLUSTER_NAME);
+ String clusterName = props.of(ES_CLUSTER_PROPERTY);
LoggerFactory.getLogger(ElasticSearch.class).info("Starting ES[{}] on port: {}", clusterName, port);
import org.picocontainer.Startable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.Server;
import org.sonar.api.platform.ServerFileSystem;
import org.sonar.core.persistence.dialect.H2;
import javax.annotation.CheckForNull;
-
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
@Override
public void start() {
LOGGER.info("SonarQube home: " + homeDir.getAbsolutePath());
- if (!homeDir.isDirectory() || !homeDir.exists()) {
- throw new IllegalStateException("SonarQube home directory does not exist");
- }
-
try {
if (getDeployDir() == null) {
throw new IllegalArgumentException("Web app directory does not exist: " + getDeployDir());
}
-
- LOGGER.info("Deploy dir: " + getDeployDir().getAbsolutePath());
FileUtils.forceMkdir(getDeployDir());
for (File subDirectory : getDeployDir().listFiles((FileFilter) FileFilterUtils.directoryFileFilter())) {
FileUtils.cleanDirectory(subDirectory);
// Line below used in last resort
"false");
Map<String, String> variables = ImmutableMap.of(
- "RAILS_LOGGER_LEVEL", profilingLevel == Profiling.Level.FULL ? "DEBUG" : "WARN",
"LOGFILE_LOGGING_FORMAT", profilingLevel == Profiling.Level.FULL ? LOGFILE_FULL_LOGGING_FORMAT : LOGFILE_STANDARD_LOGGING_FORMAT,
"CONSOLE_LOGGING_FORMAT", profilingLevel == Profiling.Level.FULL ? CONSOLE_FULL_LOGGING_FORMAT : CONSOLE_STANDARD_LOGGING_FORMAT,
"CONSOLE_ENABLED", consoleEnabled);
public static final String TYPE = "sonar.es.type";
public static final String HTTP_PORT = "sonar.es.http.port";
- public static final String NODE_PORT = "sonar.es.node.port";
+ public static final String NODE_PORT = "sonar.es.port";
public static final String CLUSTER_NAME = "sonar.es.cluster.name";
}
<configuration>
<rules>
<requireFilesSize>
- <minsize>85000000</minsize>
- <maxsize>95000000</maxsize>
+ <minsize>100000000</minsize>
+ <maxsize>105000000</maxsize>
<files>
<file>${project.build.directory}/sonarqube-${project.version}.zip</file>
</files>
# To use an environment variable, use the following syntax : ${env:NAME_OF_ENV_VARIABLE}
# For example:
# sonar.jdbc.url= ${env:SONAR_JDBC_URL}
-#
-#
-# See also the file conf/wrapper.conf for JVM advanced settings
+
#--------------------------------------------------------------------------------------------------
# TO BE DOCUMENTED - WORK IN PROGRESS
# 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.javaOpts=-server -Xmx768m -XX:MaxPermSize=160m -XX:+HeapDumpOnOutOfMemoryError
#sonar.web.jmxPort=0
# Paths are absolute or relative to installation root directory
wrapper.disable_restarts=TRUE
# Java Additional Parameters
-wrapper.java.additional.1=-Xmx32M
+wrapper.java.additional.1=-Xmx16m
# Initial JVM heap size (in MB)
wrapper.java.initmemory=16
wrapper.java.classpath.1=../../lib/common/*.jar
wrapper.java.classpath.2=../../lib/*.jar
-
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=./lib
wrapper.ntservice.interactive=false
#********************************************************************
-# restart the process if CPU is heavily loaded during 240 seconds.
wrapper.ping.timeout=0
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.process.NetworkUtils;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import java.util.Properties;
public class Installation {
+ private static final Logger LOG = LoggerFactory.getLogger(Installation.class);
// guessed from location of sonar-application.jar
private final File homeDir;
private final File tempDir, dataDir, logsDir, webDir;
- private final Map<String, String> props = new HashMap<String, String>();
+ private final Map<String, String> props;
Installation() throws URISyntaxException, IOException {
- // TODO make it configurable with sonar.path.home ?
// lib/sonar-application.jar
File appJar = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
homeDir = appJar.getParentFile().getParentFile();
+ props = initProps(homeDir);
+
+ // init file system
+ props.put("sonar.path.home", homeDir.getAbsolutePath());
+ this.dataDir = existingDir("sonar.path.data", "data");
+ this.tempDir = freshDir("sonar.path.temp", "temp");
+ this.logsDir = existingDir("sonar.path.logs", "logs");
+ this.webDir = existingDir("sonar.path.web", "web");
+
+ initElasticsearch();
+ }
+
+ /**
+ * Load conf/sonar.properties
+ */
+ private static Map<String, String> initProps(File homeDir) throws IOException {
Properties p = new Properties();
File propsFile = new File(homeDir, "conf/sonar.properties");
if (propsFile.exists()) {
} finally {
IOUtils.closeQuietly(reader);
}
+ } else {
+ LOG.info("Configuration file not found: " + propsFile.getAbsolutePath());
}
p.putAll(System.getenv());
p.putAll(System.getProperties());
p = ConfigurationUtils.interpolateEnvVariables(p);
+ Map<String, String> result = new HashMap<String, String>();
for (Map.Entry<Object, Object> entry : p.entrySet()) {
Object val = entry.getValue();
if (val != null) {
- this.props.put(entry.getKey().toString(), val.toString());
+ result.put(entry.getKey().toString(), val.toString());
}
}
+ return result;
+ }
- props.put("sonar.path.home", homeDir.getAbsolutePath());
- this.dataDir = existingDir("sonar.path.data", "data");
- this.tempDir = freshDir("sonar.path.temp", "temp");
- this.logsDir = existingDir("sonar.path.logs", "logs");
- this.webDir = existingDir("sonar.path.web", "web");
+ private void initElasticsearch() {
+ // init Elasticsearch
+ if (props.get("sonar.es.port") == null) {
+ props.put("sonar.es.port", String.valueOf(NetworkUtils.freePort()));
+ }
+ if (props.get("sonar.es.cluster.name") == null) {
+ props.put("sonar.es.cluster.name", "sonarqube");
+ }
+ props.put("sonar.es.type", "TRANSPORT");
}
File homeDir() {
return props;
}
+ String prop(String key) {
+ return props.get(key);
+ }
+
@CheckForNull
String prop(String key, @Nullable String defaultValue) {
String s = props.get(key);
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());
- }
- String esCluster = installation.prop("sonar.es.cluster.name", null);
- if (esCluster == null) {
- installation.setProp("sonar.es.cluster.name", "sonarqube");
- }
-
shutdownHook = new Thread(new Runnable() {
@Override
public void run() {
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())
+ .setJmxPort(NetworkUtils.freePort())
.addJavaOpts(opts)
+ .addJavaOpts("-Djava.io.tmpdir=" + installation.tempDir().getAbsolutePath())
+ .setEnvProperty("SONAR_HOME", installation.homeDir().getAbsolutePath())
.setClassName("org.sonar.search.ElasticSearch")
- .setArguments(installation.props())
- .setArgument("sonar.es.node.port", esPort)
+ .setProperties(installation.props())
.addClasspath(installation.starPath("lib/common"))
- .addClasspath(installation.starPath("lib/search"));
+ .addClasspath(installation.starPath("lib/search"))
+ .execute();
monitor.registerProcess(elasticsearch);
- 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");
+ opts = installation.prop("sonar.web.javaOpts", "-Xmx768m -server -XX:MaxPermSize=160m -XX:+HeapDumpOnOutOfMemoryError");
server = new ProcessWrapper("SQ")
.setWorkDir(installation.homeDir())
+ .setJmxPort(NetworkUtils.freePort())
.addJavaOpts(opts)
+ .addJavaOpts("-Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djruby.management.enabled=false")
+ .addJavaOpts("-Djava.io.tmpdir=" + installation.tempDir().getAbsolutePath())
.setClassName("org.sonar.server.app.ServerProcess")
.setEnvProperty("SONAR_HOME", installation.homeDir().getAbsolutePath())
- .setArguments(installation.props())
- .setArgument("sonar.es.type", "TRANSPORT")
+ .setProperties(installation.props())
.addClasspath(installation.starPath("extensions/jdbc-driver/mysql"))
.addClasspath(installation.starPath("extensions/jdbc-driver/mssql"))
.addClasspath(installation.starPath("extensions/jdbc-driver/oracle"))
.addClasspath(installation.starPath("extensions/jdbc-driver/postgresql"))
.addClasspath(installation.starPath("lib/common"))
- .addClasspath(installation.starPath("lib/server"));
+ .addClasspath(installation.starPath("lib/server"))
+ .execute();
monitor.registerProcess(server);
monitor.start();