private final Map<String, String> envVariables = new HashMap<>(System.getenv());
- private int processIndex = -1;
+ private final int processIndex;
- public JavaCommand(String key) {
+ public JavaCommand(String key, int processIndex) {
this.key = key;
- processIndex = Monitor.getNextProcessId();
+ this.processIndex = processIndex;
}
public String getKey() {
import org.sonar.process.DefaultProcessCommands;
import org.sonar.process.Lifecycle;
import org.sonar.process.Lifecycle.State;
-import org.sonar.process.ProcessCommands;
import org.sonar.process.ProcessUtils;
import org.sonar.process.SystemExit;
private static final Logger LOG = LoggerFactory.getLogger(Monitor.class);
private static final Timeouts TIMEOUTS = new Timeouts();
private static final long WATCH_DELAY_MS = 500L;
- private static final int CURRENT_PROCESS_NUMBER = 0;
private static int restartorInstanceCounter = 0;
+ private final int processNumber;
private final FileSystem fileSystem;
private final SystemExit systemExit;
private final boolean watchForHardStop;
private RestartorThread restartor;
@CheckForNull
HardStopWatcherThread hardStopWatcher;
- static int nextProcessId = 1;
- Monitor(FileSystem fileSystem, SystemExit exit, boolean watchForHardStop) {
+ Monitor(int processNumber, FileSystem fileSystem, SystemExit exit, boolean watchForHardStop) {
+ this.processNumber = processNumber;
this.fileSystem = fileSystem;
this.systemExit = exit;
this.watchForHardStop = watchForHardStop;
}
- public static Monitor create(FileSystem fileSystem, boolean watchForHardStop) {
- return new Monitor(fileSystem, new SystemExit(), watchForHardStop);
+ public static Monitor create(int processNumber, FileSystem fileSystem, boolean watchForHardStop) {
+ return new Monitor(processNumber, fileSystem, new SystemExit(), watchForHardStop);
}
/**
private boolean askedForStop() {
File tempDir = fileSystem.getTempDir();
- try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(tempDir, CURRENT_PROCESS_NUMBER)) {
+ try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(tempDir, processNumber)) {
if (processCommands.askedForStop()) {
return true;
}
LOG.trace(s, args);
}
- public static int getNextProcessId() {
- if (nextProcessId >= ProcessCommands.MAX_PROCESSES) {
- throw new IllegalStateException("The maximum number of processes launched has been reached " + ProcessCommands.MAX_PROCESSES);
- }
- return nextProcessId++;
- }
}
@Rule
public TemporaryFolder temp = new TemporaryFolder();
+ private int processIndex = 0;
@Test
public void test_parameters() throws Exception {
- JavaCommand command = new JavaCommand("es");
+ JavaCommand command = new JavaCommand("es", processIndex++);
command.setArgument("first_arg", "val1");
Properties args = new Properties();
@Test
public void add_java_options() {
- JavaCommand command = new JavaCommand("foo");
+ JavaCommand command = new JavaCommand("foo", processIndex++);
assertThat(command.getJavaOptions()).isEmpty();
command.addJavaOptions("");
@Test
public void fail_to_launch() throws Exception {
File tempDir = temp.newFolder();
- JavaCommand command = new JavaCommand("test");
+ JavaCommand command = new JavaCommand("test", 0);
JavaProcessLauncher launcher = new JavaProcessLauncher(new Timeouts(), tempDir);
try {
// command is not correct (missing options), java.lang.ProcessBuilder#start()
import org.junit.rules.Timeout;
import org.sonar.process.Lifecycle.State;
import org.sonar.process.NetworkUtils;
-import org.sonar.process.ProcessCommands;
import org.sonar.process.SystemExit;
import static java.util.Collections.singletonList;
private static File testJar;
+ private int processIndex = 0;
private FileSystem fileSystem = mock(FileSystem.class);
private SystemExit exit = mock(SystemExit.class);
}
}
- @Test
- public void test_too_many_processes() throws Exception {
- while (Monitor.getNextProcessId() < ProcessCommands.MAX_PROCESSES - 1) {
- }
- try {
- newDefaultMonitor(tempDir);
- } catch (IllegalStateException e) {
- assertThat(e).hasMessageStartingWith("The maximum number of processes launched has been reached ");
- } finally {
- Monitor.nextProcessId = 0;
- }
- }
-
@Test
public void fail_to_start_if_bad_class_name() throws Exception {
underTest = newDefaultMonitor(tempDir);
- JavaCommand command = new JavaCommand("test")
+ JavaCommand command = new JavaCommand("test", processIndex++)
.addClasspath(testJar.getAbsolutePath())
.setClassName("org.sonar.process.test.Unknown");
private Monitor newDefaultMonitor(File tempDir, boolean watchForHardStop) throws IOException {
when(fileSystem.getTempDir()).thenReturn(tempDir);
- return new Monitor(fileSystem, exit, watchForHardStop);
+ return new Monitor(1, fileSystem, exit, watchForHardStop);
}
/**
}
JavaCommand newCommand() {
- return new JavaCommand(commandKey)
+ return new JavaCommand(commandKey, processIndex++)
.addClasspath(testJar.getAbsolutePath())
.setClassName("org.sonar.process.test.HttpProcess")
.setArgument("httpPort", String.valueOf(httpPort));
}
private JavaCommand newStandardProcessCommand() throws IOException {
- return new JavaCommand("standard")
+ return new JavaCommand("standard", processIndex++)
.addClasspath(testJar.getAbsolutePath())
.setClassName("org.sonar.process.test.StandardProcess");
}
}
public void checkProcessNumber(int processNumber) {
- boolean result = processNumber >= 0 && processNumber < MAX_PROCESSES;
- if (!result) {
+ if (processNumber < 0 || processNumber >= MAX_PROCESSES) {
throw new IllegalArgumentException(String.format("Process number %s is not valid", processNumber));
}
}
DefaultProcessCommands.main(temp.newFolder(), processNumber);
}
+ @Test
+ public void main_fails_if_processNumber_is_MAX_PROCESSES() throws Exception {
+ int processNumber = MAX_PROCESSES;
+
+ expectProcessNumberNoValidIAE(processNumber);
+
+ DefaultProcessCommands.main(temp.newFolder(), processNumber);
+ }
+
@Test
public void secondary_fails_if_processNumber_is_less_than_0() throws Exception {
int processNumber = -2;
import org.sonar.process.monitor.Monitor;
/**
- * Entry-point of process that starts and monitors elasticsearch and web servers
+ * Entry-point of process that starts and monitors ElasticSearch, the Web Server and the Compute Engine.
*/
public class App implements Stoppable {
+ public static final int APP_PROCESS_NUMBER = 0;
+ public static final int ES_PROCESS_INDEX = 1;
+ public static final int WEBSERVER_PROCESS_INDEX = 2;
+ public static final int CESERVER_PROCESS_INDEX = 3;
+
private final Monitor monitor;
public App(AppFileSystem appFileSystem, boolean watchForHardStop) {
- this(Monitor.create(appFileSystem, watchForHardStop));
+ this(Monitor.create(APP_PROCESS_NUMBER, appFileSystem, watchForHardStop));
}
App(Monitor monitor) {
}
private static JavaCommand createESCommand(Props props, File homeDir) {
- JavaCommand elasticsearch = new JavaCommand("search");
+ JavaCommand elasticsearch = new JavaCommand("search", ES_PROCESS_INDEX);
elasticsearch
.setWorkDir(homeDir)
.addJavaOptions("-Djava.awt.headless=true")
}
private static JavaCommand createWebServerCommand(Props props, File homeDir) {
- JavaCommand webServer = new JavaCommand("web")
+ JavaCommand webServer = new JavaCommand("web", WEBSERVER_PROCESS_INDEX)
.setWorkDir(homeDir)
.addJavaOptions(ProcessProperties.WEB_ENFORCED_JVM_ARGS)
.addJavaOptions(props.nonNullValue(ProcessProperties.WEB_JAVA_OPTS))
}
private static JavaCommand createCeServerCommand(Props props, File homeDir) {
- JavaCommand webServer = new JavaCommand("ce")
+ JavaCommand webServer = new JavaCommand("ce", CESERVER_PROCESS_INDEX)
.setWorkDir(homeDir)
.setClassName("org.sonar.ce.app.CeServer")
.setArguments(props.rawProperties())