import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.sonar.application.command.AbstractCommand;
import org.sonar.application.command.CommandFactory;
-import org.sonar.application.command.EsCommand;
-import org.sonar.application.command.JavaCommand;
import org.sonar.application.config.AppSettings;
import org.sonar.application.config.ClusterSettings;
import org.sonar.application.process.Lifecycle;
private void tryToStartEs() {
SQProcess process = processesById.get(ProcessId.ELASTICSEARCH);
if (process != null) {
- tryToStartEsProcess(process, commandFactory::createEsCommand);
+ tryToStartProcess(process, commandFactory::createEsCommand);
}
}
return;
}
if (appState.isOperational(ProcessId.WEB_SERVER, false)) {
- tryToStartJavaProcess(process, () -> commandFactory.createWebCommand(false));
+ tryToStartProcess(process, () -> commandFactory.createWebCommand(false));
} else if (appState.tryToLockWebLeader()) {
- tryToStartJavaProcess(process, () -> commandFactory.createWebCommand(true));
+ tryToStartProcess(process, () -> commandFactory.createWebCommand(true));
} else {
Optional<String> leader = appState.getLeaderHostName();
if (leader.isPresent()) {
private void tryToStartCe() {
SQProcess process = processesById.get(ProcessId.COMPUTE_ENGINE);
if (process != null && appState.isOperational(ProcessId.WEB_SERVER, false) && isEsClientStartable()) {
- tryToStartJavaProcess(process, commandFactory::createCeCommand);
+ tryToStartProcess(process, commandFactory::createCeCommand);
}
}
return appState.isOperational(ProcessId.ELASTICSEARCH, requireLocalEs);
}
- private void tryToStartJavaProcess(SQProcess process, Supplier<JavaCommand> commandSupplier) {
+ private void tryToStartProcess(SQProcess process, Supplier<AbstractCommand> commandSupplier) {
tryToStart(process, () -> {
- JavaCommand command = commandSupplier.get();
- return processLauncher.launch(command);
- });
- }
-
- private void tryToStartEsProcess(SQProcess process, Supplier<EsCommand> commandSupplier) {
- tryToStart(process, () -> {
- EsCommand command = commandSupplier.get();
+ AbstractCommand command = commandSupplier.get();
return processLauncher.launch(command);
});
}
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.Properties;
import java.util.Set;
-import javax.annotation.Nullable;
+import javax.annotation.CheckForNull;
+import org.sonar.application.es.EsInstallation;
import org.sonar.process.ProcessId;
import org.sonar.process.System2;
public abstract class AbstractCommand<T extends AbstractCommand> {
// unique key among the group of commands to launch
private final ProcessId id;
- // program arguments
- private final Map<String, String> arguments = new LinkedHashMap<>();
private final Map<String, String> envVariables;
private final Set<String> suppressedEnvVariables = new HashSet<>();
private final File workDir;
+ private EsInstallation esInstallation;
protected AbstractCommand(ProcessId id, File workDir, System2 system2) {
this.id = requireNonNull(id, "ProcessId can't be null");
return (T) this;
}
- public Map<String, String> getArguments() {
- return arguments;
- }
-
- public T setArgument(String key, @Nullable String value) {
- if (value == null) {
- arguments.remove(key);
- } else {
- arguments.put(key, value);
- }
- return castThis();
- }
-
- public T setArguments(Properties args) {
- for (Map.Entry<Object, Object> entry : args.entrySet()) {
- setArgument(entry.getKey().toString(), entry.getValue() != null ? entry.getValue().toString() : null);
- }
- return castThis();
- }
-
public Map<String, String> getEnvVariables() {
return envVariables;
}
requireNonNull(value, "value can't be null"));
return castThis();
}
+
+
+ public T setEsInstallation(EsInstallation esInstallation) {
+ this.esInstallation = esInstallation;
+ return castThis();
+ }
+
+ @CheckForNull
+ public EsInstallation getEsInstallation() {
+ return esInstallation;
+ }
}
public interface CommandFactory {
- EsCommand createEsCommand();
+ AbstractCommand createEsCommand();
JavaCommand createWebCommand(boolean leader);
import java.util.Map;
import java.util.Optional;
import org.slf4j.LoggerFactory;
+import org.sonar.application.es.EsInstallation;
+import org.sonar.application.es.EsLogging;
+import org.sonar.application.es.EsSettings;
+import org.sonar.application.es.EsYmlSettings;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.System2;
-import org.sonar.application.es.EsFileSystem;
-import org.sonar.application.es.EsLogging;
-import org.sonar.application.es.EsSettings;
-import org.sonar.application.es.EsYmlSettings;
+import static org.apache.commons.lang.SystemUtils.IS_OS_WINDOWS;
import static org.sonar.process.ProcessProperties.HTTPS_PROXY_HOST;
import static org.sonar.process.ProcessProperties.HTTPS_PROXY_PORT;
import static org.sonar.process.ProcessProperties.HTTP_PROXY_HOST;
}
@Override
- public EsCommand createEsCommand() {
- EsFileSystem esFileSystem = new EsFileSystem(props);
- if (!esFileSystem.getExecutable().exists()) {
+ public AbstractCommand<?> createEsCommand() {
+ if (IS_OS_WINDOWS) {
+ return createEsCommandForWindows();
+ }
+ return createEsCommandForUnix();
+ }
+
+ private EsScriptCommand createEsCommandForUnix() {
+ EsInstallation esInstallation = new EsInstallation(props);
+ if (!esInstallation.getExecutable().exists()) {
throw new IllegalStateException("Cannot find elasticsearch binary");
}
- Map<String, String> settingsMap = new EsSettings(props, esFileSystem, System2.INSTANCE).build();
+ Map<String, String> settingsMap = new EsSettings(props, esInstallation, System2.INSTANCE).build();
- return new EsCommand(ProcessId.ELASTICSEARCH, esFileSystem.getHomeDirectory())
- .setFileSystem(esFileSystem)
- .setLog4j2Properties(new EsLogging().createProperties(props, esFileSystem.getLogDirectory()))
- .setArguments(props.rawProperties())
+ esInstallation
+ .setLog4j2Properties(new EsLogging().createProperties(props, esInstallation.getLogDirectory()))
+ .setEsJvmOptions(new EsJvmOptions()
+ .addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_OPTS)
+ .addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_ADDITIONAL_OPTS))
+ .setEsYmlSettings(new EsYmlSettings(settingsMap))
.setClusterName(settingsMap.get("cluster.name"))
.setHost(settingsMap.get("network.host"))
- .setPort(Integer.valueOf(settingsMap.get("transport.tcp.port")))
- .addEsOption("-Epath.conf=" + esFileSystem.getConfDirectory().getAbsolutePath())
+ .setPort(Integer.valueOf(settingsMap.get("transport.tcp.port")));
+
+ return new EsScriptCommand(ProcessId.ELASTICSEARCH, esInstallation.getHomeDirectory())
+ .setEsInstallation(esInstallation)
+ .addOption("-Epath.conf=" + esInstallation.getConfDirectory().getAbsolutePath())
+ .setEnvVariable("ES_JVM_OPTIONS", esInstallation.getJvmOptions().getAbsolutePath())
+ .setEnvVariable("JAVA_HOME", System.getProperties().getProperty("java.home"))
+ .suppressEnvVariable(ENV_VAR_JAVA_TOOL_OPTIONS);
+ }
+
+ private JavaCommand createEsCommandForWindows() {
+ EsInstallation esInstallation = new EsInstallation(props);
+ if (!esInstallation.getExecutable().exists()) {
+ throw new IllegalStateException("Cannot find elasticsearch binary");
+ }
+ Map<String, String> settingsMap = new EsSettings(props, esInstallation, System2.INSTANCE).build();
+
+ esInstallation
+ .setLog4j2Properties(new EsLogging().createProperties(props, esInstallation.getLogDirectory()))
.setEsJvmOptions(new EsJvmOptions()
.addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_OPTS)
.addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_ADDITIONAL_OPTS))
.setEsYmlSettings(new EsYmlSettings(settingsMap))
- .setEnvVariable("ES_JVM_OPTIONS", esFileSystem.getJvmOptions().getAbsolutePath())
+ .setClusterName(settingsMap.get("cluster.name"))
+ .setHost(settingsMap.get("network.host"))
+ .setPort(Integer.valueOf(settingsMap.get("transport.tcp.port")));
+
+ return new JavaCommand<EsJvmOptions>(ProcessId.ELASTICSEARCH, esInstallation.getHomeDirectory())
+ .setEsInstallation(esInstallation)
+ .setReadsArgumentsFromFile(false)
+ .setArgument("path.conf", esInstallation.getConfDirectory().getAbsolutePath())
+ .setJvmOptions(new EsJvmOptions()
+ .addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_OPTS)
+ .addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_ADDITIONAL_OPTS)
+ .add("-Delasticsearch")
+ .add("-Des.path.home=" + esInstallation.getHomeDirectory())
+ )
+ .setEnvVariable("ES_JVM_OPTIONS", esInstallation.getJvmOptions().getAbsolutePath())
.setEnvVariable("JAVA_HOME", System.getProperties().getProperty("java.home"))
+ .setClassName("org.elasticsearch.bootstrap.Elasticsearch")
+ .addClasspath("lib/*")
.suppressEnvVariable(ENV_VAR_JAVA_TOOL_OPTIONS);
}
addProxyJvmOptions(jvmOptions);
JavaCommand<WebJvmOptions> command = new JavaCommand<WebJvmOptions>(ProcessId.WEB_SERVER, homeDir)
+ .setReadsArgumentsFromFile(true)
.setArguments(props.rawProperties())
.setJvmOptions(jvmOptions)
// required for logback tomcat valve
addProxyJvmOptions(jvmOptions);
JavaCommand<CeJvmOptions> command = new JavaCommand<CeJvmOptions>(ProcessId.COMPUTE_ENGINE, homeDir)
+ .setReadsArgumentsFromFile(true)
.setArguments(props.rawProperties())
.setJvmOptions(jvmOptions)
.setClassName("org.sonar.ce.app.CeServer")
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.command;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import org.sonar.application.es.EsFileSystem;
-import org.sonar.application.es.EsYmlSettings;
-import org.sonar.process.ProcessId;
-import org.sonar.process.System2;
-
-public class EsCommand extends AbstractCommand<EsCommand> {
- private EsFileSystem fileSystem;
- private String clusterName;
- private String host;
- private int port;
- private Properties log4j2Properties;
- private List<String> esOptions = new ArrayList<>();
- private EsJvmOptions esJvmOptions;
- private EsYmlSettings esYmlSettings;
-
- public EsCommand(ProcessId id, File workDir) {
- super(id, workDir, System2.INSTANCE);
- }
-
- public EsFileSystem getFileSystem() {
- return fileSystem;
- }
-
- public EsCommand setFileSystem(EsFileSystem fileSystem) {
- this.fileSystem = fileSystem;
- return this;
- }
-
- public String getClusterName() {
- return clusterName;
- }
-
- public EsCommand setClusterName(String clusterName) {
- this.clusterName = clusterName;
- return this;
- }
-
- public String getHost() {
- return host;
- }
-
- public EsCommand setHost(String host) {
- this.host = host;
- return this;
- }
-
- public int getPort() {
- return port;
- }
-
- public EsCommand setPort(int port) {
- this.port = port;
- return this;
- }
-
- public Properties getLog4j2Properties() {
- return log4j2Properties;
- }
-
- public EsCommand setLog4j2Properties(Properties log4j2Properties) {
- this.log4j2Properties = log4j2Properties;
- return this;
- }
-
- public List<String> getEsOptions() {
- return esOptions;
- }
-
- public EsCommand addEsOption(String s) {
- if (!s.isEmpty()) {
- esOptions.add(s);
- }
- return this;
- }
-
- public EsCommand setEsJvmOptions(EsJvmOptions esJvmOptions) {
- this.esJvmOptions = esJvmOptions;
- return this;
- }
-
- public EsJvmOptions getEsJvmOptions() {
- return esJvmOptions;
- }
-
- public EsCommand setEsYmlSettings(EsYmlSettings esYmlSettings) {
- this.esYmlSettings = esYmlSettings;
- return this;
- }
-
- public EsYmlSettings getEsYmlSettings() {
- return esYmlSettings;
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.command;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import org.sonar.process.ProcessId;
+import org.sonar.process.System2;
+
+public class EsScriptCommand extends AbstractCommand<EsScriptCommand> {
+ private List<String> options = new ArrayList<>();
+
+ public EsScriptCommand(ProcessId id, File workDir) {
+ super(id, workDir, System2.INSTANCE);
+ }
+
+ public List<String> getOptions() {
+ return options;
+ }
+
+ public EsScriptCommand addOption(String s) {
+ if (!s.isEmpty()) {
+ options.add(s);
+ }
+ return this;
+ }
+}
import java.io.File;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import javax.annotation.Nullable;
import org.sonar.process.ProcessId;
import org.sonar.process.System2;
public class JavaCommand<T extends JvmOptions> extends AbstractCommand<JavaCommand<T>> {
+ // program arguments
+ private final Map<String, String> arguments = new LinkedHashMap<>();
// entry point
private String className;
private JvmOptions<T> jvmOptions;
// relative path to JAR files
private final List<String> classpath = new ArrayList<>();
+ private boolean readsArgumentsFromFile;
public JavaCommand(ProcessId id, File workDir) {
super(id, workDir, System2.INSTANCE);
return this;
}
+ public boolean getReadsArgumentsFromFile() {
+ return readsArgumentsFromFile;
+ }
+
+ public JavaCommand<T> setReadsArgumentsFromFile(boolean readsArgumentsFromFile) {
+ this.readsArgumentsFromFile = readsArgumentsFromFile;
+ return this;
+ }
+
+ public Map<String, String> getArguments() {
+ return arguments;
+ }
+
+ public JavaCommand<T> setArgument(String key, @Nullable String value) {
+ if (value == null) {
+ arguments.remove(key);
+ } else {
+ arguments.put(key, value);
+ }
+ return this;
+ }
+
+ public JavaCommand<T> setArguments(Properties args) {
+ for (Map.Entry<Object, Object> entry : args.entrySet()) {
+ setArgument(entry.getKey().toString(), entry.getValue() != null ? entry.getValue().toString() : null);
+ }
+ return this;
+ }
+
@Override
public String toString() {
return "JavaCommand{" + "workDir=" + getWorkDir() +
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.es;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-import org.sonar.process.ProcessProperties;
-import org.sonar.process.Props;
-
-/**
- * Holds {@link File} to the various directories of ElasticSearch distribution embedded in SonarQube and provides
- * {@link File} objects to the various files of it SonarQube cares about.
- *
- * <p>
- * This class does not ensure files nor directories actually exist.
- * </p>
- */
-public class EsFileSystem {
- private final File homeDirectory;
- private final List<File> outdatedSearchDirectories;
- private final File dataDirectory;
- private final File confDirectory;
- private final File logDirectory;
-
- public EsFileSystem(Props props) {
- File sqHomeDir = props.nonNullValueAsFile(ProcessProperties.PATH_HOME);
-
- this.homeDirectory = new File(sqHomeDir, "elasticsearch");
- this.outdatedSearchDirectories = buildOutdatedSearchDirs(props);
- this.dataDirectory = buildDataDir(props);
- this.confDirectory = buildConfDir(props);
- this.logDirectory = buildLogPath(props);
- }
-
- private static List<File> buildOutdatedSearchDirs(Props props) {
- String dataPath = props.nonNullValue(ProcessProperties.PATH_DATA);
- return Collections.singletonList(new File(dataPath, "es"));
- }
-
- private static File buildDataDir(Props props) {
- String dataPath = props.nonNullValue(ProcessProperties.PATH_DATA);
- return new File(dataPath, "es5");
- }
-
- private static File buildLogPath(Props props) {
- return props.nonNullValueAsFile(ProcessProperties.PATH_LOGS);
- }
-
- private static File buildConfDir(Props props) {
- File tempPath = props.nonNullValueAsFile(ProcessProperties.PATH_TEMP);
- return new File(new File(tempPath, "conf"), "es");
- }
-
- public File getHomeDirectory() {
- return homeDirectory;
- }
-
- public List<File> getOutdatedSearchDirectories() {
- return Collections.unmodifiableList(outdatedSearchDirectories);
- }
-
- public File getDataDirectory() {
- return dataDirectory;
- }
-
- public File getConfDirectory() {
- return confDirectory;
- }
-
- public File getLogDirectory() {
- return logDirectory;
- }
-
- public File getExecutable() {
- return new File(homeDirectory, "bin/" + getExecutableName());
- }
-
- private static String getExecutableName() {
- if (System.getProperty("os.name").startsWith("Windows")) {
- return "elasticsearch.bat";
- }
- return "elasticsearch";
- }
-
- public File getLog4j2Properties() {
- return new File(confDirectory, "log4j2.properties");
- }
-
- public File getElasticsearchYml() {
- return new File(confDirectory, "elasticsearch.yml");
- }
-
- public File getJvmOptions() {
- return new File(confDirectory, "jvm.options");
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.es;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import org.sonar.application.command.EsJvmOptions;
+import org.sonar.process.ProcessProperties;
+import org.sonar.process.Props;
+
+/**
+ * Holds {@link File} to the various directories of ElasticSearch distribution embedded in SonarQube and provides
+ * {@link File} objects to the various files of it SonarQube cares about.
+ *
+ * <p>
+ * This class does not ensure files nor directories actually exist.
+ * </p>
+ */
+public class EsInstallation {
+ private final File homeDirectory;
+ private final List<File> outdatedSearchDirectories;
+ private final File dataDirectory;
+ private final File confDirectory;
+ private final File logDirectory;
+ private EsJvmOptions esJvmOptions;
+ private EsYmlSettings esYmlSettings;
+ private Properties log4j2Properties;
+ private String clusterName;
+ private String host;
+ private int port;
+
+ public EsInstallation(Props props) {
+ File sqHomeDir = props.nonNullValueAsFile(ProcessProperties.PATH_HOME);
+
+ this.homeDirectory = new File(sqHomeDir, "elasticsearch");
+ this.outdatedSearchDirectories = buildOutdatedSearchDirs(props);
+ this.dataDirectory = buildDataDir(props);
+ this.confDirectory = buildConfDir(props);
+ this.logDirectory = buildLogPath(props);
+ }
+
+ private static List<File> buildOutdatedSearchDirs(Props props) {
+ String dataPath = props.nonNullValue(ProcessProperties.PATH_DATA);
+ return Collections.singletonList(new File(dataPath, "es"));
+ }
+
+ private static File buildDataDir(Props props) {
+ String dataPath = props.nonNullValue(ProcessProperties.PATH_DATA);
+ return new File(dataPath, "es5");
+ }
+
+ private static File buildLogPath(Props props) {
+ return props.nonNullValueAsFile(ProcessProperties.PATH_LOGS);
+ }
+
+ private static File buildConfDir(Props props) {
+ File tempPath = props.nonNullValueAsFile(ProcessProperties.PATH_TEMP);
+ return new File(new File(tempPath, "conf"), "es");
+ }
+
+ public File getHomeDirectory() {
+ return homeDirectory;
+ }
+
+ public List<File> getOutdatedSearchDirectories() {
+ return Collections.unmodifiableList(outdatedSearchDirectories);
+ }
+
+ public File getDataDirectory() {
+ return dataDirectory;
+ }
+
+ public File getConfDirectory() {
+ return confDirectory;
+ }
+
+ public File getLogDirectory() {
+ return logDirectory;
+ }
+
+ public File getExecutable() {
+ return new File(homeDirectory, "bin/" + getExecutableName());
+ }
+
+ private static String getExecutableName() {
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ return "elasticsearch.bat";
+ }
+ return "elasticsearch";
+ }
+
+ public File getLog4j2PropertiesLocation() {
+ return new File(confDirectory, "log4j2.properties");
+ }
+
+ public File getElasticsearchYml() {
+ return new File(confDirectory, "elasticsearch.yml");
+ }
+
+ public File getJvmOptions() {
+ return new File(confDirectory, "jvm.options");
+ }
+
+ public File getLibDirectory() {
+ return new File(homeDirectory, "lib");
+ }
+
+ public EsJvmOptions getEsJvmOptions() {
+ return esJvmOptions;
+ }
+
+ public EsInstallation setEsJvmOptions(EsJvmOptions esJvmOptions) {
+ this.esJvmOptions = esJvmOptions;
+ return this;
+ }
+
+ public EsYmlSettings getEsYmlSettings() {
+ return esYmlSettings;
+ }
+
+ public EsInstallation setEsYmlSettings(EsYmlSettings esYmlSettings) {
+ this.esYmlSettings = esYmlSettings;
+ return this;
+ }
+
+ public Properties getLog4j2Properties() {
+ return log4j2Properties;
+ }
+
+ public EsInstallation setLog4j2Properties(Properties log4j2Properties) {
+ this.log4j2Properties = log4j2Properties;
+ return this;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public EsInstallation setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ return this;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public EsInstallation setHost(String host) {
+ this.host = host;
+ return this;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public EsInstallation setPort(int port) {
+ this.port = port;
+ return this;
+ }
+}
private static final String STANDALONE_NODE_NAME = "sonarqube";
private final Props props;
- private final EsFileSystem fileSystem;
+ private final EsInstallation fileSystem;
private final boolean clusterEnabled;
private final String clusterName;
private final String nodeName;
- public EsSettings(Props props, EsFileSystem fileSystem, System2 system2) {
+ public EsSettings(Props props, EsInstallation fileSystem, System2 system2) {
this.props = props;
this.fileSystem = fileSystem;
import org.elasticsearch.transport.Netty4Plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.application.command.EsCommand;
+import org.sonar.application.es.EsInstallation;
+import org.sonar.process.ProcessId;
import static java.util.Collections.singletonList;
import static java.util.Collections.unmodifiableList;
private final AtomicBoolean nodeUp = new AtomicBoolean(false);
private final AtomicBoolean nodeOperational = new AtomicBoolean(false);
private final AtomicBoolean firstMasterNotDiscoveredLog = new AtomicBoolean(true);
- private final EsCommand esCommand;
+ private final EsInstallation esConfig;
private final EsConnector esConnector;
private AtomicReference<TransportClient> transportClient = new AtomicReference<>(null);
- public EsProcessMonitor(Process process, EsCommand esCommand, EsConnector esConnector) {
- super(process, esCommand.getProcessId());
- this.esCommand = esCommand;
+ public EsProcessMonitor(Process process, ProcessId processId, EsInstallation esConfig, EsConnector esConnector) {
+ super(process, processId);
+ this.esConfig = esConfig;
this.esConnector = esConnector;
}
Settings.Builder esSettings = Settings.builder();
// mandatory property defined by bootstrap process
- esSettings.put("cluster.name", esCommand.getClusterName());
+ esSettings.put("cluster.name", esConfig.getClusterName());
TransportClient nativeClient = new MinimalTransportClient(esSettings.build());
- HostAndPort host = HostAndPort.fromParts(esCommand.getHost(), esCommand.getPort());
+ HostAndPort host = HostAndPort.fromParts(esConfig.getHost(), esConfig.getPort());
addHostToClient(host, nativeClient);
if (LOG.isDebugEnabled()) {
LOG.debug("Connected to Elasticsearch node: [{}]", displayedAddresses(nativeClient));
package org.sonar.application.process;
import java.io.Closeable;
-import org.sonar.application.command.EsCommand;
-import org.sonar.application.command.JavaCommand;
+import org.sonar.application.command.AbstractCommand;
public interface ProcessLauncher extends Closeable {
void close();
/**
- * Launch an ES command.
+ * Launch a command.
*
* @throws IllegalStateException if an error occurs
*/
- ProcessMonitor launch(EsCommand esCommand);
-
- /**
- * Launch a Java command.
- *
- * @throws IllegalStateException if an error occurs
- */
- ProcessMonitor launch(JavaCommand javaCommand);
+ ProcessMonitor launch(AbstractCommand command);
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.application.command.AbstractCommand;
-import org.sonar.application.command.EsCommand;
+import org.sonar.application.command.EsScriptCommand;
import org.sonar.application.command.JavaCommand;
import org.sonar.application.command.JvmOptions;
-import org.sonar.application.es.EsFileSystem;
+import org.sonar.application.es.EsInstallation;
import org.sonar.process.ProcessId;
import org.sonar.process.sharedmemoryfile.AllProcessesCommands;
import org.sonar.process.sharedmemoryfile.ProcessCommands;
allProcessesCommands.close();
}
- @Override
- public ProcessMonitor launch(EsCommand esCommand) {
- Process process = null;
- try {
- cleanupOutdatedEsData(esCommand);
- writeConfFiles(esCommand);
- ProcessBuilder processBuilder = create(esCommand);
- logLaunchedCommand(esCommand, processBuilder);
+ public ProcessMonitor launch(AbstractCommand command) {
+ EsInstallation fileSystem = command.getEsInstallation();
+ if (fileSystem != null) {
+ cleanupOutdatedEsData(fileSystem);
+ writeConfFiles(fileSystem);
+ }
- process = processBuilder.start();
+ Process process;
+ if (command instanceof EsScriptCommand) {
+ process = launchExternal((EsScriptCommand) command);
+ } else if (command instanceof JavaCommand) {
+ process = launchJava((JavaCommand) command);
+ } else {
+ throw new IllegalStateException("Unexpected type of command: " + command.getClass());
+ }
- return new EsProcessMonitor(process, esCommand, new EsConnectorImpl());
+ ProcessId processId = command.getProcessId();
+ try {
+ if (processId == ProcessId.ELASTICSEARCH) {
+ return new EsProcessMonitor(process, processId, command.getEsInstallation(), new EsConnectorImpl());
+ } else {
+ ProcessCommands commands = allProcessesCommands.createAfterClean(processId.getIpcIndex());
+ return new ProcessCommandsProcessMonitor(process, processId, commands);
+ }
} catch (Exception e) {
// just in case
if (process != null) {
process.destroyForcibly();
}
- throw new IllegalStateException(format("Fail to launch process [%s]", esCommand.getProcessId().getKey()), e);
+ throw new IllegalStateException(format("Fail to launch monitor of process [%s]", processId.getKey()), e);
}
}
- private static void cleanupOutdatedEsData(EsCommand esCommand) {
- EsFileSystem esFileSystem = esCommand.getFileSystem();
- esFileSystem.getOutdatedSearchDirectories().forEach(outdatedDir -> {
+ private Process launchExternal(EsScriptCommand esScriptCommand) {
+ try {
+ ProcessBuilder processBuilder = create(esScriptCommand);
+ logLaunchedCommand(esScriptCommand, processBuilder);
+ return processBuilder.start();
+ } catch (Exception e) {
+ throw new IllegalStateException(format("Fail to launch process [%s]", esScriptCommand.getProcessId().getKey()), e);
+ }
+ }
+
+ private static void cleanupOutdatedEsData(EsInstallation esInstallation) {
+ esInstallation.getOutdatedSearchDirectories().forEach(outdatedDir -> {
if (outdatedDir.exists()) {
LOG.info("Deleting outdated search index data directory {}", outdatedDir.getAbsolutePath());
try {
});
}
- private static void writeConfFiles(EsCommand esCommand) {
- EsFileSystem esFileSystem = esCommand.getFileSystem();
- File confDir = esFileSystem.getConfDirectory();
+ private static void writeConfFiles(EsInstallation esInstallation) {
+ File confDir = esInstallation.getConfDirectory();
if (!confDir.exists() && !confDir.mkdirs()) {
String error = format("Failed to create temporary configuration directory [%s]", confDir.getAbsolutePath());
LOG.error(error);
}
try {
- esCommand.getEsYmlSettings().writeToYmlSettingsFile(esFileSystem.getElasticsearchYml());
- esCommand.getEsJvmOptions().writeToJvmOptionFile(esFileSystem.getJvmOptions());
- esCommand.getLog4j2Properties().store(new FileOutputStream(esFileSystem.getLog4j2Properties()), "log4j2 properties file for ES bundled in SonarQube");
+ esInstallation.getEsYmlSettings().writeToYmlSettingsFile(esInstallation.getElasticsearchYml());
+ esInstallation.getEsJvmOptions().writeToJvmOptionFile(esInstallation.getJvmOptions());
+ esInstallation.getLog4j2Properties().store(new FileOutputStream(esInstallation.getLog4j2PropertiesLocation()), "log4j2 properties file for ES bundled in SonarQube");
} catch (IOException e) {
throw new IllegalStateException("Failed to write ES configuration files", e);
}
}
- @Override
- public ProcessMonitor launch(JavaCommand javaCommand) {
- Process process = null;
+ private Process launchJava(JavaCommand javaCommand) {
ProcessId processId = javaCommand.getProcessId();
try {
- ProcessCommands commands = allProcessesCommands.createAfterClean(processId.getIpcIndex());
-
ProcessBuilder processBuilder = create(javaCommand);
logLaunchedCommand(javaCommand, processBuilder);
- process = processBuilder.start();
- return new ProcessCommandsProcessMonitor(process, processId, commands);
+ return processBuilder.start();
} catch (Exception e) {
- // just in case
- if (process != null) {
- process.destroyForcibly();
- }
throw new IllegalStateException(format("Fail to launch process [%s]", processId.getKey()), e);
}
}
}
}
- private ProcessBuilder create(EsCommand esCommand) {
+ private ProcessBuilder create(EsScriptCommand esScriptCommand) {
List<String> commands = new ArrayList<>();
- commands.add(esCommand.getFileSystem().getExecutable().getAbsolutePath());
- commands.addAll(esCommand.getEsOptions());
+ commands.add(esScriptCommand.getEsInstallation().getExecutable().getAbsolutePath());
+ commands.addAll(esScriptCommand.getOptions());
- return create(esCommand, commands);
+ return create(esScriptCommand, commands);
}
private <T extends JvmOptions> ProcessBuilder create(JavaCommand<T> javaCommand) {
commands.addAll(javaCommand.getJvmOptions().getAll());
commands.addAll(buildClasspath(javaCommand));
commands.add(javaCommand.getClassName());
- commands.add(buildPropertiesFile(javaCommand).getAbsolutePath());
+ if (javaCommand.getReadsArgumentsFromFile()) {
+ commands.add(buildPropertiesFile(javaCommand).getAbsolutePath());
+ } else {
+ javaCommand.getArguments().forEach((key, value) -> {
+ if (value != null && !value.isEmpty()) {
+ commands.add("-E" + key + "=" + value);
+ }
+ });
+ }
return create(javaCommand, commands);
}
import org.mockito.Mockito;
import org.sonar.application.command.AbstractCommand;
import org.sonar.application.command.CommandFactory;
-import org.sonar.application.command.EsCommand;
+import org.sonar.application.command.EsScriptCommand;
import org.sonar.application.command.JavaCommand;
import org.sonar.application.config.TestAppSettings;
import org.sonar.application.process.ProcessLauncher;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
- private EsCommand esCommand;
+ private EsScriptCommand esScriptCommand;
+ private JavaCommand esJavaCommand;
private JavaCommand webLeaderCommand;
private JavaCommand webFollowerCommand;
private JavaCommand ceCommand;
@Before
public void setUp() throws Exception {
File tempDir = temporaryFolder.newFolder();
- esCommand = new EsCommand(ELASTICSEARCH, tempDir);
+ esScriptCommand = new EsScriptCommand(ELASTICSEARCH, tempDir);
+ esJavaCommand = new JavaCommand(ELASTICSEARCH, tempDir);
webLeaderCommand = new JavaCommand(WEB_SERVER, tempDir);
webFollowerCommand = new JavaCommand(WEB_SERVER, tempDir);
ceCommand = new JavaCommand(COMPUTE_ENGINE, tempDir);
TestProcess web = processLauncher.waitForProcess(WEB_SERVER);
assertThat(web.isAlive()).isTrue();
assertThat(processLauncher.processes).hasSize(2);
- assertThat(processLauncher.commands).containsExactly(esCommand, webLeaderCommand);
+ assertThat(processLauncher.commands).containsExactly(esScriptCommand, webLeaderCommand);
// web becomes operational -> CE is starting
web.operational = true;
TestProcess ce = processLauncher.waitForProcess(COMPUTE_ENGINE);
assertThat(ce.isAlive()).isTrue();
assertThat(processLauncher.processes).hasSize(3);
- assertThat(processLauncher.commands).containsExactly(esCommand, webLeaderCommand, ceCommand);
+ assertThat(processLauncher.commands).containsExactly(esScriptCommand, webLeaderCommand, ceCommand);
// all processes are up
processLauncher.processes.values().forEach(p -> assertThat(p.isAlive()).isTrue());
private class TestCommandFactory implements CommandFactory {
@Override
- public EsCommand createEsCommand() {
- return esCommand;
+ public EsScriptCommand createEsCommand() {
+ return esScriptCommand;
}
@Override
private ProcessId makeStartupFail = null;
@Override
- public ProcessMonitor launch(EsCommand esCommand) {
- return launchImpl(esCommand);
- }
-
- @Override
- public ProcessMonitor launch(JavaCommand javaCommand) {
- return launchImpl(javaCommand);
+ public ProcessMonitor launch(AbstractCommand command) {
+ return launchImpl(command);
}
private ProcessMonitor launchImpl(AbstractCommand<?> javaCommand) {
};
}
- @Test
- public void test_command_with_complete_information() throws Exception {
- File workDir = temp.newFolder();
- AbstractCommand command = new AbstractCommand(ProcessId.ELASTICSEARCH, workDir, System2.INSTANCE) {
-
- };
-
- command.setArgument("first_arg", "val1");
- Properties args = new Properties();
- args.setProperty("second_arg", "val2");
- command.setArguments(args);
-
- command.setEnvVariable("JAVA_COMMAND_TEST", "1000");
-
- assertThat(command.toString()).isNotNull();
- assertThat(command.getWorkDir()).isSameAs(workDir);
-
- // copy current env variables
- assertThat(command.getEnvVariables().get("JAVA_COMMAND_TEST")).isEqualTo("1000");
- assertThat(command.getEnvVariables().size()).isEqualTo(System.getenv().size() + 1);
- }
-
@Test
public void setEnvVariable_fails_with_NPE_if_key_is_null() throws IOException {
File workDir = temp.newFolder();
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
+import org.sonar.application.es.EsInstallation;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
Properties props = new Properties();
props.setProperty("sonar.search.host", "localhost");
- EsCommand esCommand = newFactory(props).createEsCommand();
+ AbstractCommand esCommand = newFactory(props).createEsCommand();
+ EsInstallation esConfig = esCommand.getEsInstallation();
- assertThat(esCommand.getClusterName()).isEqualTo("sonarqube");
- assertThat(esCommand.getHost()).isNotEmpty();
- assertThat(esCommand.getPort()).isEqualTo(9001);
- assertThat(esCommand.getEsJvmOptions().getAll())
+ assertThat(esConfig.getClusterName()).isEqualTo("sonarqube");
+ assertThat(esConfig.getHost()).isNotEmpty();
+ assertThat(esConfig.getPort()).isEqualTo(9001);
+ assertThat(esConfig.getEsJvmOptions().getAll())
// enforced values
.contains("-XX:+UseConcMarkSweepGC", "-server", "-Dfile.encoding=UTF-8")
// default settings
.contains("-Xms512m", "-Xmx512m", "-XX:+HeapDumpOnOutOfMemoryError");
File esConfDir = new File(tempDir, "conf/es");
- assertThat(esCommand.getEsOptions()).containsOnly("-Epath.conf=" + esConfDir.getAbsolutePath());
assertThat(esCommand.getEnvVariables())
.contains(entry("ES_JVM_OPTIONS", new File(esConfDir, "jvm.options").getAbsolutePath()))
.containsKey("JAVA_HOME");
- assertThat(esCommand.getEsYmlSettings()).isNotNull();
+ assertThat(esConfig.getEsYmlSettings()).isNotNull();
- assertThat(esCommand.getLog4j2Properties())
+ assertThat(esConfig.getLog4j2Properties())
.contains(entry("appender.file_es.fileName", new File(logsDir, "es.log").getAbsolutePath()));
assertThat(esCommand.getSuppressedEnvVariables()).containsOnly("JAVA_TOOL_OPTIONS");
props.setProperty("sonar.search.port", "1234");
props.setProperty("sonar.search.javaOpts", "-Xms10G -Xmx10G");
- EsCommand command = newFactory(props).createEsCommand();
+ AbstractCommand esCommand = newFactory(props).createEsCommand();
+ EsInstallation esConfig = esCommand.getEsInstallation();
- assertThat(command.getClusterName()).isEqualTo("foo");
- assertThat(command.getPort()).isEqualTo(1234);
- assertThat(command.getEsJvmOptions().getAll())
+ assertThat(esConfig.getClusterName()).isEqualTo("foo");
+ assertThat(esConfig.getPort()).isEqualTo(1234);
+ assertThat(esConfig.getEsJvmOptions().getAll())
// enforced values
.contains("-XX:+UseConcMarkSweepGC", "-server", "-Dfile.encoding=UTF-8")
// user settings
.contains("-Xmx512m", "-Xms128m", "-XX:+HeapDumpOnOutOfMemoryError");
assertThat(command.getProcessId()).isEqualTo(ProcessId.WEB_SERVER);
assertThat(command.getEnvVariables())
- .containsKey("JAVA_HOME");
+ .isNotEmpty();
assertThat(command.getArguments())
// default settings
.contains(entry("sonar.web.javaOpts", "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError"))
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.es;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Properties;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.process.ProcessProperties;
-import org.sonar.process.Props;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class EsFileSystemTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @Test
- public void constructor_fails_with_IAE_if_sq_home_property_is_not_defined() {
- Props props = new Props(new Properties());
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Property sonar.path.home is not set");
-
- new EsFileSystem(props);
- }
-
- @Test
- public void constructor_fails_with_IAE_if_temp_dir_property_is_not_defined() throws IOException {
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Property sonar.path.temp is not set");
-
- new EsFileSystem(props);
- }
-
- @Test
- public void constructor_fails_with_IAE_if_data_dir_property_is_not_defined() throws IOException {
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Missing property: sonar.path.data");
-
- new EsFileSystem(props);
- }
-
- @Test
- public void getHomeDirectory_is_elasticsearch_subdirectory_of_sq_home_directory() throws IOException {
- File sqHomeDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- assertThat(underTest.getHomeDirectory()).isEqualTo(new File(sqHomeDir, "elasticsearch"));
- }
-
- @Test
- public void override_data_dir() throws Exception {
- File sqHomeDir = temp.newFolder();
- File tempDir = temp.newFolder();
- File dataDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
-
- props.set(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- assertThat(underTest.getDataDirectory()).isEqualTo(new File(dataDir, "es5"));
- }
-
- @Test
- public void getLogDirectory_is_configured_with_non_nullable_PATH_LOG_variable() throws IOException {
- File sqHomeDir = temp.newFolder();
- File logDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- assertThat(underTest.getLogDirectory()).isEqualTo(logDir);
- }
-
- @Test
- public void conf_directory_is_conf_es_subdirectory_of_sq_temp_directory() throws IOException {
- File tempDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- assertThat(underTest.getConfDirectory()).isEqualTo(new File(tempDir, "conf/es"));
- }
-
- @Test
- public void getExecutable_resolve_executable_for_platform() throws IOException {
- File sqHomeDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- if (System.getProperty("os.name").startsWith("Windows")) {
- assertThat(underTest.getExecutable()).isEqualTo(new File(sqHomeDir, "elasticsearch/bin/elasticsearch.bat"));
- } else {
- assertThat(underTest.getExecutable()).isEqualTo(new File(sqHomeDir, "elasticsearch/bin/elasticsearch"));
- }
- }
-
- @Test
- public void getLog4j2Properties_is_in_es_conf_directory() throws IOException {
- File tempDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- assertThat(underTest.getLog4j2Properties()).isEqualTo(new File(tempDir, "conf/es/log4j2.properties"));
- }
-
- @Test
- public void getElasticsearchYml_is_in_es_conf_directory() throws IOException {
- File tempDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- assertThat(underTest.getElasticsearchYml()).isEqualTo(new File(tempDir, "conf/es/elasticsearch.yml"));
- }
-
- @Test
- public void getJvmOptions_is_in_es_conf_directory() throws IOException {
- File tempDir = temp.newFolder();
- Props props = new Props(new Properties());
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
-
- EsFileSystem underTest = new EsFileSystem(props);
-
- assertThat(underTest.getJvmOptions()).isEqualTo(new File(tempDir, "conf/es/jvm.options"));
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.es;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.process.ProcessProperties;
+import org.sonar.process.Props;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class EsInstallationTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void constructor_fails_with_IAE_if_sq_home_property_is_not_defined() {
+ Props props = new Props(new Properties());
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Property sonar.path.home is not set");
+
+ new EsInstallation(props);
+ }
+
+ @Test
+ public void constructor_fails_with_IAE_if_temp_dir_property_is_not_defined() throws IOException {
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Property sonar.path.temp is not set");
+
+ new EsInstallation(props);
+ }
+
+ @Test
+ public void constructor_fails_with_IAE_if_data_dir_property_is_not_defined() throws IOException {
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Missing property: sonar.path.data");
+
+ new EsInstallation(props);
+ }
+
+ @Test
+ public void getHomeDirectory_is_elasticsearch_subdirectory_of_sq_home_directory() throws IOException {
+ File sqHomeDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ assertThat(underTest.getHomeDirectory()).isEqualTo(new File(sqHomeDir, "elasticsearch"));
+ }
+
+ @Test
+ public void override_data_dir() throws Exception {
+ File sqHomeDir = temp.newFolder();
+ File tempDir = temp.newFolder();
+ File dataDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+
+ props.set(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ assertThat(underTest.getDataDirectory()).isEqualTo(new File(dataDir, "es5"));
+ }
+
+ @Test
+ public void getLogDirectory_is_configured_with_non_nullable_PATH_LOG_variable() throws IOException {
+ File sqHomeDir = temp.newFolder();
+ File logDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ assertThat(underTest.getLogDirectory()).isEqualTo(logDir);
+ }
+
+ @Test
+ public void conf_directory_is_conf_es_subdirectory_of_sq_temp_directory() throws IOException {
+ File tempDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ assertThat(underTest.getConfDirectory()).isEqualTo(new File(tempDir, "conf/es"));
+ }
+
+ @Test
+ public void getExecutable_resolve_executable_for_platform() throws IOException {
+ File sqHomeDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ assertThat(underTest.getExecutable()).isEqualTo(new File(sqHomeDir, "elasticsearch/bin/elasticsearch.bat"));
+ } else {
+ assertThat(underTest.getExecutable()).isEqualTo(new File(sqHomeDir, "elasticsearch/bin/elasticsearch"));
+ }
+ }
+
+ @Test
+ public void getLog4j2Properties_is_in_es_conf_directory() throws IOException {
+ File tempDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ assertThat(underTest.getLog4j2PropertiesLocation()).isEqualTo(new File(tempDir, "conf/es/log4j2.properties"));
+ }
+
+ @Test
+ public void getElasticsearchYml_is_in_es_conf_directory() throws IOException {
+ File tempDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ assertThat(underTest.getElasticsearchYml()).isEqualTo(new File(tempDir, "conf/es/elasticsearch.yml"));
+ }
+
+ @Test
+ public void getJvmOptions_is_in_es_conf_directory() throws IOException {
+ File tempDir = temp.newFolder();
+ Props props = new Props(new Properties());
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+
+ EsInstallation underTest = new EsInstallation(props);
+
+ assertThat(underTest.getJvmOptions()).isEqualTo(new File(tempDir, "conf/es/jvm.options"));
+ }
+}
this.listAppender = ListAppender.attachMemoryAppenderToLoggerOf(EsSettings.class);
Props props = minimalProps();
System2 system2 = mock(System2.class);
- new EsSettings(props, new EsFileSystem(props), system2);
+ new EsSettings(props, new EsInstallation(props), system2);
assertThat(listAppender.getLogs()).isEmpty();
}
Props props = minimalProps();
System2 system2 = mock(System2.class);
when(system2.getenv("ES_JVM_OPTIONS")).thenReturn(" ");
- new EsSettings(props, new EsFileSystem(props), system2);
+ new EsSettings(props, new EsInstallation(props), system2);
assertThat(listAppender.getLogs()).isEmpty();
}
Props props = minimalProps();
System2 system2 = mock(System2.class);
when(system2.getenv("ES_JVM_OPTIONS")).thenReturn(randomAlphanumeric(2));
- new EsSettings(props, new EsFileSystem(props), system2);
+ new EsSettings(props, new EsInstallation(props), system2);
assertThat(listAppender.getLogs())
.extracting(ILoggingEvent::getMessage)
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(CLUSTER_NAME, "sonarqube");
- EsSettings esSettings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE);
+ EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);
Map<String, String> generated = esSettings.build();
assertThat(generated.get("transport.tcp.port")).isEqualTo("1234");
props.set(ProcessProperties.CLUSTER_ENABLED, "true");
props.set(ProcessProperties.CLUSTER_NODE_NAME, "node-1");
- EsSettings esSettings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE);
+ EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);
Map<String, String> generated = esSettings.build();
assertThat(generated.get("cluster.name")).isEqualTo("sonarqube-1");
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
- EsSettings esSettings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE);
+ EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);
Map<String, String> generated = esSettings.build();
assertThat(generated.get("node.name")).startsWith("sonarqube-");
}
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
- EsSettings esSettings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE);
+ EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);
Map<String, String> generated = esSettings.build();
assertThat(generated.get("node.name")).isEqualTo("sonarqube");
}
@Test
public void path_properties_are_values_from_EsFileSystem_argument() throws IOException {
- EsFileSystem mockedEsFileSystem = mock(EsFileSystem.class);
- when(mockedEsFileSystem.getHomeDirectory()).thenReturn(new File("/foo/home"));
- when(mockedEsFileSystem.getConfDirectory()).thenReturn(new File("/foo/conf"));
- when(mockedEsFileSystem.getLogDirectory()).thenReturn(new File("/foo/log"));
- when(mockedEsFileSystem.getDataDirectory()).thenReturn(new File("/foo/data"));
+ EsInstallation mockedEsInstallation = mock(EsInstallation.class);
+ when(mockedEsInstallation.getHomeDirectory()).thenReturn(new File("/foo/home"));
+ when(mockedEsInstallation.getConfDirectory()).thenReturn(new File("/foo/conf"));
+ when(mockedEsInstallation.getLogDirectory()).thenReturn(new File("/foo/log"));
+ when(mockedEsInstallation.getDataDirectory()).thenReturn(new File("/foo/data"));
- EsSettings underTest = new EsSettings(minProps(new Random().nextBoolean()), mockedEsFileSystem, System2.INSTANCE);
+ EsSettings underTest = new EsSettings(minProps(new Random().nextBoolean()), mockedEsInstallation, System2.INSTANCE);
Map<String, String> generated = underTest.build();
assertThat(generated.get("path.data")).isEqualTo("/foo/data");
public void set_discovery_settings_if_cluster_is_enabled() throws Exception {
Props props = minProps(CLUSTER_ENABLED);
props.set(CLUSTER_SEARCH_HOSTS, "1.2.3.4:9000,1.2.3.5:8080");
- Map<String, String> settings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE).build();
+ Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();
assertThat(settings.get("discovery.zen.ping.unicast.hosts")).isEqualTo("1.2.3.4:9000,1.2.3.5:8080");
assertThat(settings.get("discovery.zen.minimum_master_nodes")).isEqualTo("2");
Props props = minProps(CLUSTER_ENABLED);
props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "ꝱꝲꝳପ");
- EsSettings underTest = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE);
+ EsSettings underTest = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Value of property sonar.search.minimumMasterNodes is not an integer:");
public void cluster_is_enabled_with_defined_minimum_master_nodes() throws Exception {
Props props = minProps(CLUSTER_ENABLED);
props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "5");
- Map<String, String> settings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE).build();
+ Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();
assertThat(settings.get("discovery.zen.minimum_master_nodes")).isEqualTo("5");
}
public void cluster_is_enabled_with_defined_initialTimeout() throws Exception {
Props props = minProps(CLUSTER_ENABLED);
props.set(ProcessProperties.SEARCH_INITIAL_STATE_TIMEOUT, "10s");
- Map<String, String> settings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE).build();
+ Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();
assertThat(settings.get("discovery.initial_state_timeout")).isEqualTo("10s");
}
public void in_standalone_initialTimeout_is_not_overridable() throws Exception {
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_INITIAL_STATE_TIMEOUT, "10s");
- Map<String, String> settings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE).build();
+ Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();
assertThat(settings.get("discovery.initial_state_timeout")).isEqualTo("30s");
}
public void in_standalone_minimumMasterNodes_is_not_overridable() throws Exception {
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "5");
- Map<String, String> settings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE).build();
+ Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();
assertThat(settings.get("discovery.zen.minimum_master_nodes")).isEqualTo("1");
}
public void enable_http_connector() throws Exception {
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_HTTP_PORT, "9010");
- Map<String, String> settings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE).build();
+ Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();
assertThat(settings.get("http.port")).isEqualTo("9010");
assertThat(settings.get("http.host")).isEqualTo("127.0.0.1");
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_HTTP_PORT, "9010");
props.set(ProcessProperties.SEARCH_HOST, "127.0.0.2");
- Map<String, String> settings = new EsSettings(props, new EsFileSystem(props), System2.INSTANCE).build();
+ Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();
assertThat(settings.get("http.port")).isEqualTo("9010");
assertThat(settings.get("http.host")).isEqualTo("127.0.0.2");
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
+import java.util.Properties;
import java.util.Random;
import org.elasticsearch.client.transport.NoNodeAvailableException;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.discovery.MasterNotDiscoveredException;
import org.junit.Test;
import org.slf4j.LoggerFactory;
+import org.sonar.application.es.EsInstallation;
import org.sonar.process.ProcessId;
-import org.sonar.application.command.EsCommand;
+import org.sonar.process.Props;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
public void isOperational_should_return_false_if_Elasticsearch_is_RED() throws Exception {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus(any())).thenReturn(ClusterHealthStatus.RED);
- EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, getEsConfig(), esConnector);
assertThat(underTest.isOperational()).isFalse();
}
public void isOperational_should_return_true_if_Elasticsearch_is_YELLOW() throws Exception {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus(any())).thenReturn(ClusterHealthStatus.YELLOW);
- EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, getEsConfig(), esConnector);
assertThat(underTest.isOperational()).isTrue();
}
public void isOperational_should_return_true_if_Elasticsearch_is_GREEN() throws Exception {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus(any())).thenReturn(ClusterHealthStatus.GREEN);
- EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, getEsConfig(), esConnector);
assertThat(underTest.isOperational()).isTrue();
}
public void isOperational_should_return_true_if_Elasticsearch_was_GREEN_once() throws Exception {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus(any())).thenReturn(ClusterHealthStatus.GREEN);
- EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, getEsConfig(), esConnector);
assertThat(underTest.isOperational()).isTrue();
when(esConnector.getClusterHealthStatus(any())).thenReturn(ClusterHealthStatus.RED);
when(esConnector.getClusterHealthStatus(any()))
.thenThrow(new NoNodeAvailableException("test"))
.thenReturn(ClusterHealthStatus.GREEN);
- EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, getEsConfig(), esConnector);
assertThat(underTest.isOperational()).isTrue();
}
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus(any()))
.thenThrow(new RuntimeException("test"));
- EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, getEsConfig(), esConnector);
assertThat(underTest.isOperational()).isFalse();
}
when(esConnector.getClusterHealthStatus(any()))
.thenThrow(new MasterNotDiscoveredException("Master not elected -test-"));
- EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, getEsConfig(), esConnector);
assertThat(underTest.isOperational()).isFalse();
assertThat(memoryAppender.events).isNotEmpty();
assertThat(memoryAppender.events)
);
}
- private EsCommand getEsCommand() throws IOException {
+ private EsInstallation getEsConfig() throws IOException {
Path tempDirectory = Files.createTempDirectory(getClass().getSimpleName());
- return new EsCommand(ProcessId.ELASTICSEARCH, tempDirectory.toFile())
+ Properties properties = new Properties();
+ properties.setProperty("sonar.path.home", "/imaginary/path");
+ properties.setProperty("sonar.path.data", "/imaginary/path");
+ properties.setProperty("sonar.path.temp", "/imaginary/path");
+ properties.setProperty("sonar.path.logs", "/imaginary/path");
+ return new EsInstallation(new Props(properties))
.setHost("localhost")
.setPort(new Random().nextInt(40000));
}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
-import org.sonar.application.command.EsCommand;
import org.sonar.application.command.EsJvmOptions;
+import org.sonar.application.command.EsScriptCommand;
import org.sonar.application.command.JavaCommand;
import org.sonar.application.command.JvmOptions;
-import org.sonar.application.es.EsFileSystem;
+import org.sonar.application.es.EsInstallation;
import org.sonar.application.es.EsYmlSettings;
import org.sonar.process.ProcessId;
import org.sonar.process.Props;
File tempDir = temp.newFolder();
TestProcessBuilder processBuilder = new TestProcessBuilder();
ProcessLauncher underTest = new ProcessLauncherImpl(tempDir, commands, () -> processBuilder);
- JavaCommand<JvmOptions> command = new JavaCommand<>(ProcessId.ELASTICSEARCH, temp.newFolder());
+ JavaCommand<JvmOptions> command = new JavaCommand<>(ProcessId.WEB_SERVER, temp.newFolder());
+ command.setReadsArgumentsFromFile(true);
command.setArgument("foo", "bar");
command.setArgument("baz", "woo");
command.setJvmOptions(new JvmOptions<>());
entry("foo", "bar"),
entry("baz", "woo"),
entry("process.terminationTimeout", "60000"),
- entry("process.key", ProcessId.ELASTICSEARCH.getKey()),
- entry("process.index", String.valueOf(ProcessId.ELASTICSEARCH.getIpcIndex())),
+ entry("process.key", ProcessId.WEB_SERVER.getKey()),
+ entry("process.index", String.valueOf(ProcessId.WEB_SERVER.getIpcIndex())),
entry("process.sharedDir", tempDir.getAbsolutePath()));
}
}
+ @Test
+ public void temporary_properties_file_can_be_avoided() throws Exception {
+ File tempDir = temp.newFolder();
+ TestProcessBuilder processBuilder = new TestProcessBuilder();
+ ProcessLauncher underTest = new ProcessLauncherImpl(tempDir, commands, () -> processBuilder);
+ JavaCommand<JvmOptions> command = new JavaCommand<>(ProcessId.WEB_SERVER, temp.newFolder());
+ command.setReadsArgumentsFromFile(false);
+ command.setArgument("foo", "bar");
+ command.setArgument("baz", "woo");
+ command.setJvmOptions(new JvmOptions<>());
+
+ underTest.launch(command);
+
+ String propsFilePath = processBuilder.commands.get(processBuilder.commands.size() - 1);
+ File file = new File(propsFilePath);
+ assertThat(file).doesNotExist();
+ }
+
@Test
public void clean_up_old_es_data() throws Exception {
File tempDir = temp.newFolder();
File dataDir = temp.newFolder();
File logDir = temp.newFolder();
ProcessLauncher underTest = new ProcessLauncherImpl(tempDir, commands, () -> new TestProcessBuilder());
- EsCommand command = createEsCommand(tempDir, homeDir, dataDir, logDir);
+ EsScriptCommand command = createEsScriptCommand(tempDir, homeDir, dataDir, logDir);
File outdatedEsDir = new File(dataDir, "es");
assertThat(outdatedEsDir.mkdir()).isTrue();
File dataDir = temp.newFolder();
File logDir = temp.newFolder();
ProcessLauncher underTest = new ProcessLauncherImpl(tempDir, commands, () -> new TestProcessBuilder());
- EsCommand command = createEsCommand(tempDir, homeDir, dataDir, logDir);
+ EsScriptCommand command = createEsScriptCommand(tempDir, homeDir, dataDir, logDir);
File outdatedEsDir = new File(dataDir, "es");
assertThat(outdatedEsDir.exists()).isFalse();
underTest.launch(new JavaCommand(ProcessId.ELASTICSEARCH, temp.newFolder()));
}
- private EsCommand createEsCommand(File tempDir, File homeDir, File dataDir, File logDir) throws IOException {
- EsCommand command = new EsCommand(ProcessId.ELASTICSEARCH, temp.newFolder());
+ private EsScriptCommand createEsScriptCommand(File tempDir, File homeDir, File dataDir, File logDir) throws IOException {
+ EsScriptCommand command = new EsScriptCommand(ProcessId.ELASTICSEARCH, temp.newFolder());
Props props = new Props(new Properties());
props.set("sonar.path.temp", tempDir.getAbsolutePath());
props.set("sonar.path.home", homeDir.getAbsolutePath());
props.set("sonar.path.data", dataDir.getAbsolutePath());
props.set("sonar.path.logs", logDir.getAbsolutePath());
- command.setFileSystem(new EsFileSystem(props));
- command.setEsYmlSettings(mock(EsYmlSettings.class));
- command.setEsJvmOptions(mock(EsJvmOptions.class));
- command.setLog4j2Properties(new Properties());
+ command.setEsInstallation(new EsInstallation(props)
+ .setEsYmlSettings(mock(EsYmlSettings.class))
+ .setEsJvmOptions(mock(EsJvmOptions.class))
+ .setLog4j2Properties(new Properties()));
return command;
}