Browse Source

SONAR-12043 some clarification class renaming in sonar-main module

tags/7.8
Sébastien Lesaint 5 years ago
parent
commit
e75c740bad
23 changed files with 175 additions and 178 deletions
  1. 0
    0
      server/sonar-main/.attach_pid25465
  2. 1
    2
      server/sonar-main/src/main/java/org/sonar/application/HardStopRequestWatcherImpl.java
  3. 1
    1
      server/sonar-main/src/main/java/org/sonar/application/NodeLifecycle.java
  4. 3
    2
      server/sonar-main/src/main/java/org/sonar/application/ProcessLauncher.java
  5. 7
    4
      server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java
  6. 17
    18
      server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java
  7. 1
    1
      server/sonar-main/src/main/java/org/sonar/application/StopRequestWatcher.java
  8. 3
    3
      server/sonar-main/src/main/java/org/sonar/application/process/AbstractManagedProcess.java
  9. 8
    8
      server/sonar-main/src/main/java/org/sonar/application/process/EsManagedProcess.java
  10. 1
    1
      server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcess.java
  11. 3
    3
      server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessEventListener.java
  12. 20
    20
      server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessHandler.java
  13. 9
    9
      server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessLifecycle.java
  14. 2
    2
      server/sonar-main/src/main/java/org/sonar/application/process/ProcessCommandsManagedProcess.java
  15. 1
    1
      server/sonar-main/src/main/java/org/sonar/application/process/ProcessLifecycleListener.java
  16. 1
    2
      server/sonar-main/src/test/java/org/sonar/application/HardStopRequestWatcherImplTest.java
  17. 3
    2
      server/sonar-main/src/test/java/org/sonar/application/ProcessLauncherImplTest.java
  18. 18
    19
      server/sonar-main/src/test/java/org/sonar/application/SchedulerImplTest.java
  19. 9
    9
      server/sonar-main/src/test/java/org/sonar/application/process/EsManagedProcessTest.java
  20. 48
    48
      server/sonar-main/src/test/java/org/sonar/application/process/ManagedProcessHandlerTest.java
  21. 14
    14
      server/sonar-main/src/test/java/org/sonar/application/process/ManagedProcessLifecycleTest.java
  22. 5
    5
      server/sonar-main/src/test/java/org/sonar/application/process/ProcessCommandsManagedProcessTest.java
  23. 0
    4
      sonar-application/src/main/java/org/sonar/application/App.java

+ 0
- 0
server/sonar-main/.attach_pid25465 View File


server/sonar-main/src/main/java/org/sonar/application/process/HardStopRequestWatcherImpl.java → server/sonar-main/src/main/java/org/sonar/application/HardStopRequestWatcherImpl.java View File

@@ -17,9 +17,8 @@
* 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.process;
package org.sonar.application;

import org.sonar.application.FileSystem;
import org.sonar.application.config.AppSettings;
import org.sonar.process.ProcessId;
import org.sonar.process.sharedmemoryfile.DefaultProcessCommands;

+ 1
- 1
server/sonar-main/src/main/java/org/sonar/application/NodeLifecycle.java View File

@@ -35,7 +35,7 @@ import static org.sonar.application.NodeLifecycle.State.STOPPED;
import static org.sonar.application.NodeLifecycle.State.STOPPING;

/**
* Lifecycle of the cluster node, consolidating the states
* ManagedProcessLifecycle of the cluster node, consolidating the states
* of child processes.
*/
class NodeLifecycle {

server/sonar-main/src/main/java/org/sonar/application/process/ProcessLauncher.java → server/sonar-main/src/main/java/org/sonar/application/ProcessLauncher.java View File

@@ -17,10 +17,11 @@
* 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.process;
package org.sonar.application;

import java.io.Closeable;
import org.sonar.application.command.AbstractCommand;
import org.sonar.application.process.ManagedProcess;

public interface ProcessLauncher extends Closeable {

@@ -32,5 +33,5 @@ public interface ProcessLauncher extends Closeable {
*
* @throws IllegalStateException if an error occurs
*/
ProcessMonitor launch(AbstractCommand command);
ManagedProcess launch(AbstractCommand command);
}

server/sonar-main/src/main/java/org/sonar/application/process/ProcessLauncherImpl.java → server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java View File

@@ -17,7 +17,7 @@
* 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.process;
package org.sonar.application;

import com.google.common.net.HostAndPort;
import java.io.File;
@@ -38,6 +38,9 @@ import org.sonar.application.command.JavaCommand;
import org.sonar.application.command.JvmOptions;
import org.sonar.application.es.EsConnectorImpl;
import org.sonar.application.es.EsInstallation;
import org.sonar.application.process.EsManagedProcess;
import org.sonar.application.process.ManagedProcess;
import org.sonar.application.process.ProcessCommandsManagedProcess;
import org.sonar.process.FileUtils2;
import org.sonar.process.ProcessId;
import org.sonar.process.sharedmemoryfile.AllProcessesCommands;
@@ -74,7 +77,7 @@ public class ProcessLauncherImpl implements ProcessLauncher {
allProcessesCommands.close();
}

public ProcessMonitor launch(AbstractCommand command) {
public ManagedProcess launch(AbstractCommand command) {
EsInstallation esInstallation = command.getEsInstallation();
if (esInstallation != null) {
cleanupOutdatedEsData(esInstallation);
@@ -95,10 +98,10 @@ public class ProcessLauncherImpl implements ProcessLauncher {
if (processId == ProcessId.ELASTICSEARCH) {
checkArgument(esInstallation != null, "Incorrect configuration EsInstallation is null");
EsConnectorImpl esConnector = new EsConnectorImpl(esInstallation.getClusterName(), singleton(HostAndPort.fromParts(esInstallation.getHost(), esInstallation.getPort())));
return new EsProcessMonitor(process, processId, esConnector);
return new EsManagedProcess(process, processId, esConnector);
} else {
ProcessCommands commands = allProcessesCommands.createAfterClean(processId.getIpcIndex());
return new ProcessCommandsProcessMonitor(process, processId, commands);
return new ProcessCommandsManagedProcess(process, processId, commands);
}
} catch (Exception e) {
// just in case

+ 17
- 18
server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java View File

@@ -32,17 +32,16 @@ import org.sonar.application.command.AbstractCommand;
import org.sonar.application.command.CommandFactory;
import org.sonar.application.config.AppSettings;
import org.sonar.application.config.ClusterSettings;
import org.sonar.application.process.Lifecycle;
import org.sonar.application.process.ProcessEventListener;
import org.sonar.application.process.ProcessLauncher;
import org.sonar.application.process.ManagedProcessLifecycle;
import org.sonar.application.process.ManagedProcessEventListener;
import org.sonar.application.process.ProcessLifecycleListener;
import org.sonar.application.process.ProcessMonitor;
import org.sonar.application.process.SQProcess;
import org.sonar.application.process.ManagedProcess;
import org.sonar.application.process.ManagedProcessHandler;
import org.sonar.process.ProcessId;

import static org.sonar.application.process.SQProcess.Timeout.newTimeout;
import static org.sonar.application.process.ManagedProcessHandler.Timeout.newTimeout;

public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLifecycleListener, AppStateListener {
public class SchedulerImpl implements Scheduler, ManagedProcessEventListener, ProcessLifecycleListener, AppStateListener {

private static final Logger LOG = LoggerFactory.getLogger(SchedulerImpl.class);

@@ -57,12 +56,12 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
private final AtomicBoolean firstWaitingEsLog = new AtomicBoolean(true);
private final AtomicBoolean restartRequested = new AtomicBoolean(false);
private final AtomicBoolean restarting = new AtomicBoolean(false);
private final EnumMap<ProcessId, SQProcess> processesById = new EnumMap<>(ProcessId.class);
private final EnumMap<ProcessId, ManagedProcessHandler> processesById = new EnumMap<>(ProcessId.class);
private final AtomicInteger operationalCountDown = new AtomicInteger();
private final AtomicInteger stopCountDown = new AtomicInteger(0);
private HardStopperThread hardStopperThread;
private RestarterThread restarterThread;
private long processWatcherDelayMs = SQProcess.DEFAULT_WATCHER_DELAY_MS;
private long processWatcherDelayMs = ManagedProcessHandler.DEFAULT_WATCHER_DELAY_MS;

public SchedulerImpl(AppSettings settings, AppReloader appReloader, CommandFactory commandFactory,
ProcessLauncher processLauncher, AppState appState) {
@@ -87,7 +86,7 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
processesById.clear();

for (ProcessId processId : ClusterSettings.getEnabledProcesses(settings)) {
SQProcess process = SQProcess.builder(processId)
ManagedProcessHandler process = ManagedProcessHandler.builder(processId)
.addProcessLifecycleListener(this)
.addEventListener(this)
.setWatcherDelayMs(processWatcherDelayMs)
@@ -108,14 +107,14 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
}

private void tryToStartEs() {
SQProcess process = processesById.get(ProcessId.ELASTICSEARCH);
ManagedProcessHandler process = processesById.get(ProcessId.ELASTICSEARCH);
if (process != null) {
tryToStartProcess(process, commandFactory::createEsCommand);
}
}

private void tryToStartWeb() {
SQProcess process = processesById.get(ProcessId.WEB_SERVER);
ManagedProcessHandler process = processesById.get(ProcessId.WEB_SERVER);
if (process == null) {
return;
}
@@ -140,7 +139,7 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
}

private void tryToStartCe() {
SQProcess process = processesById.get(ProcessId.COMPUTE_ENGINE);
ManagedProcessHandler process = processesById.get(ProcessId.COMPUTE_ENGINE);
if (process != null && appState.isOperational(ProcessId.WEB_SERVER, true) && isEsClientStartable()) {
tryToStartProcess(process, commandFactory::createCeCommand);
}
@@ -151,14 +150,14 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
return appState.isOperational(ProcessId.ELASTICSEARCH, requireLocalEs);
}

private void tryToStartProcess(SQProcess process, Supplier<AbstractCommand> commandSupplier) {
private void tryToStartProcess(ManagedProcessHandler process, Supplier<AbstractCommand> commandSupplier) {
tryToStart(process, () -> {
AbstractCommand command = commandSupplier.get();
return processLauncher.launch(command);
});
}

private void tryToStart(SQProcess process, Supplier<ProcessMonitor> processMonitorSupplier) {
private void tryToStart(ManagedProcessHandler process, Supplier<ManagedProcess> processMonitorSupplier) {
try {
process.start(processMonitorSupplier);
} catch (RuntimeException e) {
@@ -180,7 +179,7 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
* Returns immediately if the process is disabled in configuration.
*/
private void hardStopProcess(ProcessId processId) {
SQProcess process = processesById.get(processId);
ManagedProcessHandler process = processesById.get(processId);
if (process != null) {
process.hardStop();
}
@@ -217,7 +216,7 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
}

@Override
public void onProcessEvent(ProcessId processId, Type type) {
public void onManagedProcessEvent(ProcessId processId, Type type) {
if (type == Type.OPERATIONAL) {
onProcessOperational(processId);
} else if (type == Type.ASK_FOR_RESTART && restartRequested.compareAndSet(false, true)) {
@@ -242,7 +241,7 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi
}

@Override
public void onProcessState(ProcessId processId, Lifecycle.State to) {
public void onProcessState(ProcessId processId, ManagedProcessLifecycle.State to) {
switch (to) {
case STOPPED:
onProcessStop(processId);

server/sonar-main/src/main/java/org/sonar/application/process/StopRequestWatcher.java → server/sonar-main/src/main/java/org/sonar/application/StopRequestWatcher.java View File

@@ -17,7 +17,7 @@
* 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.process;
package org.sonar.application;

/**
* Background thread that checks if a stop request

server/sonar-main/src/main/java/org/sonar/application/process/AbstractProcessMonitor.java → server/sonar-main/src/main/java/org/sonar/application/process/AbstractManagedProcess.java View File

@@ -28,15 +28,15 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.process.ProcessId;

abstract class AbstractProcessMonitor implements ProcessMonitor {
abstract class AbstractManagedProcess implements ManagedProcess {

private static final Logger LOG = LoggerFactory.getLogger(AbstractProcessMonitor.class);
private static final Logger LOG = LoggerFactory.getLogger(AbstractManagedProcess.class);
private static final int EXPECTED_EXIT_VALUE = 0;

protected final Process process;
private final ProcessId processId;

protected AbstractProcessMonitor(Process process, ProcessId processId) {
protected AbstractManagedProcess(Process process, ProcessId processId) {
this.process = process;
this.processId = processId;
}

server/sonar-main/src/main/java/org/sonar/application/process/EsProcessMonitor.java → server/sonar-main/src/main/java/org/sonar/application/process/EsManagedProcess.java View File

@@ -27,14 +27,14 @@ import org.slf4j.LoggerFactory;
import org.sonar.application.es.EsConnector;
import org.sonar.process.ProcessId;

import static org.sonar.application.process.EsProcessMonitor.Status.CONNECTION_REFUSED;
import static org.sonar.application.process.EsProcessMonitor.Status.GREEN;
import static org.sonar.application.process.EsProcessMonitor.Status.KO;
import static org.sonar.application.process.EsProcessMonitor.Status.RED;
import static org.sonar.application.process.EsProcessMonitor.Status.YELLOW;
import static org.sonar.application.process.EsManagedProcess.Status.CONNECTION_REFUSED;
import static org.sonar.application.process.EsManagedProcess.Status.GREEN;
import static org.sonar.application.process.EsManagedProcess.Status.KO;
import static org.sonar.application.process.EsManagedProcess.Status.RED;
import static org.sonar.application.process.EsManagedProcess.Status.YELLOW;

public class EsProcessMonitor extends AbstractProcessMonitor {
private static final Logger LOG = LoggerFactory.getLogger(EsProcessMonitor.class);
public class EsManagedProcess extends AbstractManagedProcess {
private static final Logger LOG = LoggerFactory.getLogger(EsManagedProcess.class);
private static final int WAIT_FOR_UP_DELAY_IN_MILLIS = 100;
private static final int WAIT_FOR_UP_TIMEOUT = 10 * 60; /* 1min */

@@ -44,7 +44,7 @@ public class EsProcessMonitor extends AbstractProcessMonitor {
private final EsConnector esConnector;


public EsProcessMonitor(Process process, ProcessId processId, EsConnector esConnector) {
public EsManagedProcess(Process process, ProcessId processId, EsConnector esConnector) {
super(process, processId);
this.esConnector = esConnector;
}

server/sonar-main/src/main/java/org/sonar/application/process/ProcessMonitor.java → server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcess.java View File

@@ -22,7 +22,7 @@ package org.sonar.application.process;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

public interface ProcessMonitor {
public interface ManagedProcess {

/**
* @see Process#getInputStream()

server/sonar-main/src/main/java/org/sonar/application/process/ProcessEventListener.java → server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessEventListener.java View File

@@ -22,7 +22,7 @@ package org.sonar.application.process;
import org.sonar.process.ProcessId;

@FunctionalInterface
public interface ProcessEventListener {
public interface ManagedProcessEventListener {

enum Type {
OPERATIONAL,
@@ -33,11 +33,11 @@ public interface ProcessEventListener {
* This method is called when the process with the specified {@link ProcessId}
* sends the event through the ipc shared memory.
* Note that there can be a delay since the instant the process sets the flag
* (see {@link SQProcess#WATCHER_DELAY_MS}).
* (see {@link ManagedProcessHandler#WATCHER_DELAY_MS}).
*
* Call blocks the process watcher. Implementations should be asynchronous and
* fork a new thread if call can be long.
*/
void onProcessEvent(ProcessId processId, Type type);
void onManagedProcessEvent(ProcessId processId, Type type);

}

server/sonar-main/src/main/java/org/sonar/application/process/SQProcess.java → server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessHandler.java View File

@@ -32,18 +32,18 @@ import org.sonar.process.ProcessId;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;

public class SQProcess {
public class ManagedProcessHandler {

public static final long DEFAULT_WATCHER_DELAY_MS = 500L;
private static final Logger LOG = LoggerFactory.getLogger(SQProcess.class);
private static final Logger LOG = LoggerFactory.getLogger(ManagedProcessHandler.class);

private final ProcessId processId;
private final Lifecycle lifecycle;
private final List<ProcessEventListener> eventListeners;
private final ManagedProcessLifecycle lifecycle;
private final List<ManagedProcessEventListener> eventListeners;
private final Timeout hardStopTimeout;
private final long watcherDelayMs;

private ProcessMonitor process;
private ManagedProcess process;
private StreamGobbler stdOutGobbler;
private StreamGobbler stdErrGobbler;
private final StopWatcher stopWatcher;
@@ -52,9 +52,9 @@ public class SQProcess {
// to listeners
private final AtomicBoolean operational = new AtomicBoolean(false);

private SQProcess(Builder builder) {
private ManagedProcessHandler(Builder builder) {
this.processId = requireNonNull(builder.processId, "processId can't be null");
this.lifecycle = new Lifecycle(this.processId, builder.lifecycleListeners);
this.lifecycle = new ManagedProcessLifecycle(this.processId, builder.lifecycleListeners);
this.eventListeners = builder.eventListeners;
this.hardStopTimeout = builder.hardStopTimeout;
this.watcherDelayMs = builder.watcherDelayMs;
@@ -62,8 +62,8 @@ public class SQProcess {
this.eventWatcher = new EventWatcher();
}

public boolean start(Supplier<ProcessMonitor> commandLauncher) {
if (!lifecycle.tryToMoveTo(Lifecycle.State.STARTING)) {
public boolean start(Supplier<ManagedProcess> commandLauncher) {
if (!lifecycle.tryToMoveTo(ManagedProcessLifecycle.State.STARTING)) {
// has already been started
return false;
}
@@ -71,7 +71,7 @@ public class SQProcess {
this.process = commandLauncher.get();
} catch (RuntimeException e) {
LOG.error("Fail to launch process [{}]", processId.getKey(), e);
lifecycle.tryToMoveTo(Lifecycle.State.STOPPED);
lifecycle.tryToMoveTo(ManagedProcessLifecycle.State.STOPPED);
throw e;
}
this.stdOutGobbler = new StreamGobbler(process.getInputStream(), processId.getKey());
@@ -82,7 +82,7 @@ public class SQProcess {
this.eventWatcher.start();
// Could be improved by checking the status "up" in shared memory.
// Not a problem so far as this state is not used by listeners.
lifecycle.tryToMoveTo(Lifecycle.State.STARTED);
lifecycle.tryToMoveTo(ManagedProcessLifecycle.State.STARTED);
return true;
}

@@ -90,7 +90,7 @@ public class SQProcess {
return processId;
}

Lifecycle.State getState() {
ManagedProcessLifecycle.State getState() {
return lifecycle.getState();
}

@@ -99,7 +99,7 @@ public class SQProcess {
* executed). It depends on OS.
*/
public void hardStop() {
if (lifecycle.tryToMoveTo(Lifecycle.State.HARD_STOPPING)) {
if (lifecycle.tryToMoveTo(ManagedProcessLifecycle.State.HARD_STOPPING)) {
hardStopImpl();
if (process != null && process.isAlive()) {
LOG.info("{} failed to stop in a quick fashion. Killing it.", processId.getKey());
@@ -155,18 +155,18 @@ public class SQProcess {
StreamGobbler.waitUntilFinish(stdErrGobbler);
stdErrGobbler.interrupt();
}
lifecycle.tryToMoveTo(Lifecycle.State.STOPPED);
lifecycle.tryToMoveTo(ManagedProcessLifecycle.State.STOPPED);
}

void refreshState() {
if (process.isAlive()) {
if (!operational.get() && process.isOperational()) {
operational.set(true);
eventListeners.forEach(l -> l.onProcessEvent(processId, ProcessEventListener.Type.OPERATIONAL));
eventListeners.forEach(l -> l.onManagedProcessEvent(processId, ManagedProcessEventListener.Type.OPERATIONAL));
}
if (process.askedForRestart()) {
process.acknowledgeAskForRestart();
eventListeners.forEach(l -> l.onProcessEvent(processId, ProcessEventListener.Type.ASK_FOR_RESTART));
eventListeners.forEach(l -> l.onManagedProcessEvent(processId, ManagedProcessEventListener.Type.ASK_FOR_RESTART));
}
} else {
stopForcibly();
@@ -237,7 +237,7 @@ public class SQProcess {

public static class Builder {
private final ProcessId processId;
private final List<ProcessEventListener> eventListeners = new ArrayList<>();
private final List<ManagedProcessEventListener> eventListeners = new ArrayList<>();
private final List<ProcessLifecycleListener> lifecycleListeners = new ArrayList<>();
private long watcherDelayMs = DEFAULT_WATCHER_DELAY_MS;
private Timeout hardStopTimeout = new Timeout(1, TimeUnit.MINUTES);
@@ -246,7 +246,7 @@ public class SQProcess {
this.processId = processId;
}

public Builder addEventListener(ProcessEventListener listener) {
public Builder addEventListener(ManagedProcessEventListener listener) {
this.eventListeners.add(listener);
return this;
}
@@ -269,8 +269,8 @@ public class SQProcess {
return this;
}

public SQProcess build() {
return new SQProcess(this);
public ManagedProcessHandler build() {
return new ManagedProcessHandler(this);
}
}


server/sonar-main/src/main/java/org/sonar/application/process/Lifecycle.java → server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessLifecycle.java View File

@@ -30,30 +30,30 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.process.ProcessId;

import static org.sonar.application.process.Lifecycle.State.INIT;
import static org.sonar.application.process.Lifecycle.State.STARTED;
import static org.sonar.application.process.Lifecycle.State.STARTING;
import static org.sonar.application.process.Lifecycle.State.STOPPED;
import static org.sonar.application.process.Lifecycle.State.HARD_STOPPING;
import static org.sonar.application.process.ManagedProcessLifecycle.State.INIT;
import static org.sonar.application.process.ManagedProcessLifecycle.State.STARTED;
import static org.sonar.application.process.ManagedProcessLifecycle.State.STARTING;
import static org.sonar.application.process.ManagedProcessLifecycle.State.STOPPED;
import static org.sonar.application.process.ManagedProcessLifecycle.State.HARD_STOPPING;

public class Lifecycle {
public class ManagedProcessLifecycle {

public enum State {
INIT, STARTING, STARTED, HARD_STOPPING, STOPPED
}

private static final Logger LOG = LoggerFactory.getLogger(Lifecycle.class);
private static final Logger LOG = LoggerFactory.getLogger(ManagedProcessLifecycle.class);
private static final Map<State, Set<State>> TRANSITIONS = buildTransitions();

private final ProcessId processId;
private final List<ProcessLifecycleListener> listeners;
private State state;

public Lifecycle(ProcessId processId, List<ProcessLifecycleListener> listeners) {
public ManagedProcessLifecycle(ProcessId processId, List<ProcessLifecycleListener> listeners) {
this(processId, listeners, INIT);
}

Lifecycle(ProcessId processId, List<ProcessLifecycleListener> listeners, State initialState) {
ManagedProcessLifecycle(ProcessId processId, List<ProcessLifecycleListener> listeners, State initialState) {
this.processId = processId;
this.listeners = listeners;
this.state = initialState;

server/sonar-main/src/main/java/org/sonar/application/process/ProcessCommandsProcessMonitor.java → server/sonar-main/src/main/java/org/sonar/application/process/ProcessCommandsManagedProcess.java View File

@@ -24,11 +24,11 @@ import org.sonar.process.sharedmemoryfile.ProcessCommands;

import static java.util.Objects.requireNonNull;

class ProcessCommandsProcessMonitor extends AbstractProcessMonitor {
public class ProcessCommandsManagedProcess extends AbstractManagedProcess {

private final ProcessCommands commands;

ProcessCommandsProcessMonitor(Process process, ProcessId processId, ProcessCommands commands) {
public ProcessCommandsManagedProcess(Process process, ProcessId processId, ProcessCommands commands) {
super(process, processId);
this.commands = requireNonNull(commands, "commands can't be null");
}

+ 1
- 1
server/sonar-main/src/main/java/org/sonar/application/process/ProcessLifecycleListener.java View File

@@ -31,6 +31,6 @@ public interface ProcessLifecycleListener {
* Call blocks the process watcher. Implementations should be asynchronous and
* fork a new thread if call can be long.
*/
void onProcessState(ProcessId processId, Lifecycle.State state);
void onProcessState(ProcessId processId, ManagedProcessLifecycle.State state);

}

server/sonar-main/src/test/java/org/sonar/application/process/HardStopRequestWatcherImplTest.java → server/sonar-main/src/test/java/org/sonar/application/HardStopRequestWatcherImplTest.java View File

@@ -17,7 +17,7 @@
* 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.process;
package org.sonar.application;

import java.io.IOException;
import org.junit.Rule;
@@ -26,7 +26,6 @@ import org.junit.rules.DisableOnDebug;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.sonar.application.FileSystem;
import org.sonar.application.config.AppSettings;
import org.sonar.process.sharedmemoryfile.ProcessCommands;


server/sonar-main/src/test/java/org/sonar/application/process/ProcessLauncherImplTest.java → server/sonar-main/src/test/java/org/sonar/application/ProcessLauncherImplTest.java View File

@@ -17,7 +17,7 @@
* 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.process;
package org.sonar.application;

import java.io.File;
import java.io.FileReader;
@@ -36,6 +36,7 @@ import org.sonar.application.command.JavaCommand;
import org.sonar.application.command.JvmOptions;
import org.sonar.application.es.EsInstallation;
import org.sonar.application.es.EsYmlSettings;
import org.sonar.application.process.ManagedProcess;
import org.sonar.process.ProcessId;
import org.sonar.process.Props;
import org.sonar.process.sharedmemoryfile.AllProcessesCommands;
@@ -71,7 +72,7 @@ public class ProcessLauncherImplTest {
.add("-Dfoo2=bar2"));
command.setEsInstallation(createEsInstallation());

ProcessMonitor monitor = underTest.launch(command);
ManagedProcess monitor = underTest.launch(command);

assertThat(monitor).isNotNull();
assertThat(processBuilder.started).isTrue();

+ 18
- 19
server/sonar-main/src/test/java/org/sonar/application/SchedulerImplTest.java View File

@@ -42,8 +42,7 @@ import org.sonar.application.command.CommandFactory;
import org.sonar.application.command.EsScriptCommand;
import org.sonar.application.command.JavaCommand;
import org.sonar.application.config.TestAppSettings;
import org.sonar.application.process.ProcessLauncher;
import org.sonar.application.process.ProcessMonitor;
import org.sonar.application.process.ManagedProcess;
import org.sonar.process.ProcessId;
import org.sonar.process.cluster.hz.HazelcastMember;

@@ -104,14 +103,14 @@ public class SchedulerImplTest {
underTest.schedule();

// elasticsearch does not have preconditions to start
TestProcess es = processLauncher.waitForProcess(ELASTICSEARCH);
TestManagedProcess es = processLauncher.waitForProcess(ELASTICSEARCH);
assertThat(es.isAlive()).isTrue();
assertThat(processLauncher.processes).hasSize(1);

// elasticsearch becomes operational -> web leader is starting
es.operational = true;
waitForAppStateOperational(appState, ELASTICSEARCH);
TestProcess web = processLauncher.waitForProcess(WEB_SERVER);
TestManagedProcess web = processLauncher.waitForProcess(WEB_SERVER);
assertThat(web.isAlive()).isTrue();
assertThat(processLauncher.processes).hasSize(2);
assertThat(processLauncher.commands).containsExactly(esScriptCommand, webLeaderCommand);
@@ -119,7 +118,7 @@ public class SchedulerImplTest {
// web becomes operational -> CE is starting
web.operational = true;
waitForAppStateOperational(appState, WEB_SERVER);
TestProcess ce = processLauncher.waitForProcess(COMPUTE_ENGINE);
TestManagedProcess ce = processLauncher.waitForProcess(COMPUTE_ENGINE);
assertThat(ce.isAlive()).isTrue();
assertThat(processLauncher.processes).hasSize(3);
assertThat(processLauncher.commands).containsExactly(esScriptCommand, webLeaderCommand, ceCommand);
@@ -229,7 +228,7 @@ public class SchedulerImplTest {
SchedulerImpl underTest = newScheduler(true);
underTest.schedule();

TestProcess web = processLauncher.waitForProcessAlive(WEB_SERVER);
TestManagedProcess web = processLauncher.waitForProcessAlive(WEB_SERVER);
web.operational = true;
processLauncher.waitForProcessAlive(COMPUTE_ENGINE);
assertThat(processLauncher.processes).hasSize(2);
@@ -342,28 +341,28 @@ public class SchedulerImplTest {
}

private class TestProcessLauncher implements ProcessLauncher {
private final EnumMap<ProcessId, TestProcess> processes = new EnumMap<>(ProcessId.class);
private final EnumMap<ProcessId, TestManagedProcess> processes = new EnumMap<>(ProcessId.class);
private final List<AbstractCommand<?>> commands = synchronizedList(new ArrayList<>());
private ProcessId makeStartupFail = null;

@Override
public ProcessMonitor launch(AbstractCommand command) {
public ManagedProcess launch(AbstractCommand command) {
return launchImpl(command);
}

private ProcessMonitor launchImpl(AbstractCommand<?> javaCommand) {
private ManagedProcess launchImpl(AbstractCommand<?> javaCommand) {
commands.add(javaCommand);
if (makeStartupFail == javaCommand.getProcessId()) {
throw new IllegalStateException("cannot start " + javaCommand.getProcessId());
}
TestProcess process = new TestProcess(javaCommand.getProcessId());
TestManagedProcess process = new TestManagedProcess(javaCommand.getProcessId());
processes.put(javaCommand.getProcessId(), process);
return process;
}

private TestProcess waitForProcess(ProcessId id) throws InterruptedException {
private TestManagedProcess waitForProcess(ProcessId id) throws InterruptedException {
while (true) {
TestProcess p = processes.get(id);
TestManagedProcess p = processes.get(id);
if (p != null) {
return p;
}
@@ -371,9 +370,9 @@ public class SchedulerImplTest {
}
}

private TestProcess waitForProcessAlive(ProcessId id) throws InterruptedException {
private TestManagedProcess waitForProcessAlive(ProcessId id) throws InterruptedException {
while (true) {
TestProcess p = processes.get(id);
TestManagedProcess p = processes.get(id);
if (p != null && p.isAlive()) {
return p;
}
@@ -381,9 +380,9 @@ public class SchedulerImplTest {
}
}

private TestProcess waitForProcessDown(ProcessId id) throws InterruptedException {
private TestManagedProcess waitForProcessDown(ProcessId id) throws InterruptedException {
while (true) {
TestProcess p = processes.get(id);
TestManagedProcess p = processes.get(id);
if (p != null && !p.isAlive()) {
return p;
}
@@ -393,19 +392,19 @@ public class SchedulerImplTest {

@Override
public void close() {
for (TestProcess process : processes.values()) {
for (TestManagedProcess process : processes.values()) {
process.destroyForcibly();
}
}
}

private class TestProcess implements ProcessMonitor, AutoCloseable {
private class TestManagedProcess implements ManagedProcess, AutoCloseable {
private final ProcessId processId;
private final CountDownLatch alive = new CountDownLatch(1);
private boolean operational = false;
private boolean askedForRestart = false;

private TestProcess(ProcessId processId) {
private TestManagedProcess(ProcessId processId) {
this.processId = processId;
}


server/sonar-main/src/test/java/org/sonar/application/process/EsProcessMonitorTest.java → server/sonar-main/src/test/java/org/sonar/application/process/EsManagedProcessTest.java View File

@@ -38,13 +38,13 @@ import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class EsProcessMonitorTest {
public class EsManagedProcessTest {

@Test
public void isOperational_should_return_false_if_Elasticsearch_is_RED() {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus()).thenReturn(ClusterHealthStatus.RED);
EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
assertThat(underTest.isOperational()).isFalse();
}

@@ -52,7 +52,7 @@ public class EsProcessMonitorTest {
public void isOperational_should_return_true_if_Elasticsearch_is_YELLOW() {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus()).thenReturn(ClusterHealthStatus.YELLOW);
EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
assertThat(underTest.isOperational()).isTrue();
}

@@ -60,7 +60,7 @@ public class EsProcessMonitorTest {
public void isOperational_should_return_true_if_Elasticsearch_is_GREEN() {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus()).thenReturn(ClusterHealthStatus.GREEN);
EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
assertThat(underTest.isOperational()).isTrue();
}

@@ -68,7 +68,7 @@ public class EsProcessMonitorTest {
public void isOperational_should_return_true_if_Elasticsearch_was_GREEN_once() {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus()).thenReturn(ClusterHealthStatus.GREEN);
EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
assertThat(underTest.isOperational()).isTrue();

when(esConnector.getClusterHealthStatus()).thenReturn(ClusterHealthStatus.RED);
@@ -81,7 +81,7 @@ public class EsProcessMonitorTest {
when(esConnector.getClusterHealthStatus())
.thenThrow(new NoNodeAvailableException("test"))
.thenReturn(ClusterHealthStatus.GREEN);
EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
assertThat(underTest.isOperational()).isTrue();
}

@@ -90,7 +90,7 @@ public class EsProcessMonitorTest {
EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus())
.thenThrow(new RuntimeException("test"));
EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
assertThat(underTest.isOperational()).isFalse();
}

@@ -101,13 +101,13 @@ public class EsProcessMonitorTest {
lc.reset();
memoryAppender.setContext(lc);
memoryAppender.start();
lc.getLogger(EsProcessMonitor.class).addAppender(memoryAppender);
lc.getLogger(EsManagedProcess.class).addAppender(memoryAppender);

EsConnector esConnector = mock(EsConnector.class);
when(esConnector.getClusterHealthStatus())
.thenThrow(new MasterNotDiscoveredException("Master not elected -test-"));

EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector);
assertThat(underTest.isOperational()).isFalse();
assertThat(memoryAppender.events).isNotEmpty();
assertThat(memoryAppender.events)

server/sonar-main/src/test/java/org/sonar/application/process/SQProcessTest.java → server/sonar-main/src/test/java/org/sonar/application/process/ManagedProcessHandlerTest.java View File

@@ -36,9 +36,9 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.sonar.application.process.SQProcess.Timeout.newTimeout;
import static org.sonar.application.process.ManagedProcessHandler.Timeout.newTimeout;

public class SQProcessTest {
public class ManagedProcessHandlerTest {

private static final ProcessId A_PROCESS_ID = ProcessId.ELASTICSEARCH;

@@ -49,91 +49,91 @@ public class SQProcessTest {

@Test
public void initial_state_is_INIT() {
SQProcess underTest = SQProcess.builder(A_PROCESS_ID).build();
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID).build();

assertThat(underTest.getProcessId()).isEqualTo(A_PROCESS_ID);
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.INIT);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.INIT);
}

@Test
public void start_and_stop_process() {
ProcessLifecycleListener listener = mock(ProcessLifecycleListener.class);
SQProcess underTest = SQProcess.builder(A_PROCESS_ID)
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID)
.addProcessLifecycleListener(listener)
.build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
assertThat(underTest.start(() -> testProcess)).isTrue();
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STARTED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STARTED);
assertThat(testProcess.isAlive()).isTrue();
assertThat(testProcess.streamsClosed).isFalse();
verify(listener).onProcessState(A_PROCESS_ID, Lifecycle.State.STARTED);
verify(listener).onProcessState(A_PROCESS_ID, ManagedProcessLifecycle.State.STARTED);

testProcess.close();
// do not wait next run of watcher threads
underTest.refreshState();
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STOPPED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STOPPED);
assertThat(testProcess.isAlive()).isFalse();
assertThat(testProcess.streamsClosed).isTrue();
verify(listener).onProcessState(A_PROCESS_ID, Lifecycle.State.STOPPED);
verify(listener).onProcessState(A_PROCESS_ID, ManagedProcessLifecycle.State.STOPPED);
}
}

@Test
public void start_does_not_nothing_if_already_started_once() {
SQProcess underTest = SQProcess.builder(A_PROCESS_ID).build();
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID).build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
assertThat(underTest.start(() -> testProcess)).isTrue();
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STARTED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STARTED);

assertThat(underTest.start(() -> {throw new IllegalStateException();})).isFalse();
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STARTED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STARTED);
}
}

@Test
public void start_throws_exception_and_move_to_state_STOPPED_if_execution_of_command_fails() {
SQProcess underTest = SQProcess.builder(A_PROCESS_ID).build();
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID).build();

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("error");

underTest.start(() -> {throw new IllegalStateException("error");});
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STOPPED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STOPPED);
}

@Test
public void send_event_when_process_is_operational() {
ProcessEventListener listener = mock(ProcessEventListener.class);
SQProcess underTest = SQProcess.builder(A_PROCESS_ID)
ManagedProcessEventListener listener = mock(ManagedProcessEventListener.class);
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID)
.addEventListener(listener)
.build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
underTest.start(() -> testProcess);

testProcess.operational = true;
underTest.refreshState();

verify(listener).onProcessEvent(A_PROCESS_ID, ProcessEventListener.Type.OPERATIONAL);
verify(listener).onManagedProcessEvent(A_PROCESS_ID, ManagedProcessEventListener.Type.OPERATIONAL);
}
verifyNoMoreInteractions(listener);
}

@Test
public void operational_event_is_sent_once() {
ProcessEventListener listener = mock(ProcessEventListener.class);
SQProcess underTest = SQProcess.builder(A_PROCESS_ID)
ManagedProcessEventListener listener = mock(ManagedProcessEventListener.class);
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID)
.addEventListener(listener)
.build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
underTest.start(() -> testProcess);
testProcess.operational = true;

underTest.refreshState();
verify(listener).onProcessEvent(A_PROCESS_ID, ProcessEventListener.Type.OPERATIONAL);
verify(listener).onManagedProcessEvent(A_PROCESS_ID, ManagedProcessEventListener.Type.OPERATIONAL);

// second run
underTest.refreshState();
@@ -143,17 +143,17 @@ public class SQProcessTest {

@Test
public void send_event_when_process_requests_for_restart() {
ProcessEventListener listener = mock(ProcessEventListener.class);
SQProcess underTest = SQProcess.builder(A_PROCESS_ID)
ManagedProcessEventListener listener = mock(ManagedProcessEventListener.class);
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID)
.addEventListener(listener)
.setWatcherDelayMs(1L)
.build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
underTest.start(() -> testProcess);

testProcess.askedForRestart = true;
verify(listener, timeout(10_000)).onProcessEvent(A_PROCESS_ID, ProcessEventListener.Type.ASK_FOR_RESTART);
verify(listener, timeout(10_000)).onManagedProcessEvent(A_PROCESS_ID, ManagedProcessEventListener.Type.ASK_FOR_RESTART);

// flag is reset so that next run does not trigger again the event
underTest.refreshState();
@@ -164,31 +164,31 @@ public class SQProcessTest {

@Test
public void stopForcibly_stops_the_process_without_graceful_request_for_stop() {
SQProcess underTest = SQProcess.builder(A_PROCESS_ID).build();
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID).build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
underTest.start(() -> testProcess);

underTest.stopForcibly();
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STOPPED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STOPPED);
assertThat(testProcess.askedForHardStop).isFalse();
assertThat(testProcess.destroyedForcibly).isTrue();

// second execution of stopForcibly does nothing. It's still stopped.
underTest.stopForcibly();
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STOPPED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STOPPED);
}
}

@Test
public void process_stops_after_graceful_request_for_stop() throws Exception {
ProcessLifecycleListener listener = mock(ProcessLifecycleListener.class);
SQProcess underTest = SQProcess.builder(A_PROCESS_ID)
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID)
.addProcessLifecycleListener(listener)
.setHardStopTimeout(newTimeout(1, TimeUnit.HOURS))
.build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
underTest.start(() -> testProcess);

Thread stopperThread = new Thread(underTest::hardStop);
@@ -201,8 +201,8 @@ public class SQProcessTest {
while (!testProcess.askedForHardStop) {
Thread.sleep(1L);
}
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.HARD_STOPPING);
verify(listener).onProcessState(A_PROCESS_ID, Lifecycle.State.HARD_STOPPING);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.HARD_STOPPING);
verify(listener).onProcessState(A_PROCESS_ID, ManagedProcessLifecycle.State.HARD_STOPPING);

// process stopped
testProcess.close();
@@ -210,20 +210,20 @@ public class SQProcessTest {
// waiting for stopper thread to detect and handle the stop
stopperThread.join();

assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STOPPED);
verify(listener).onProcessState(A_PROCESS_ID, Lifecycle.State.STOPPED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STOPPED);
verify(listener).onProcessState(A_PROCESS_ID, ManagedProcessLifecycle.State.STOPPED);
}
}

@Test
public void process_is_stopped_forcibly_if_graceful_stop_is_too_long() throws Exception {
ProcessLifecycleListener listener = mock(ProcessLifecycleListener.class);
SQProcess underTest = SQProcess.builder(A_PROCESS_ID)
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID)
.addProcessLifecycleListener(listener)
.setHardStopTimeout(newTimeout(1, TimeUnit.MILLISECONDS))
.build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
underTest.start(() -> testProcess);

underTest.hardStop();
@@ -232,35 +232,35 @@ public class SQProcessTest {
assertThat(testProcess.askedForHardStop).isTrue();
assertThat(testProcess.destroyedForcibly).isTrue();
assertThat(testProcess.isAlive()).isFalse();
assertThat(underTest.getState()).isEqualTo(Lifecycle.State.STOPPED);
verify(listener).onProcessState(A_PROCESS_ID, Lifecycle.State.STOPPED);
assertThat(underTest.getState()).isEqualTo(ManagedProcessLifecycle.State.STOPPED);
verify(listener).onProcessState(A_PROCESS_ID, ManagedProcessLifecycle.State.STOPPED);
}
}

@Test
public void process_requests_are_listened_on_regular_basis() {
ProcessEventListener listener = mock(ProcessEventListener.class);
SQProcess underTest = SQProcess.builder(A_PROCESS_ID)
ManagedProcessEventListener listener = mock(ManagedProcessEventListener.class);
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID)
.addEventListener(listener)
.setWatcherDelayMs(1L)
.build();

try (TestProcess testProcess = new TestProcess()) {
try (TestManagedProcess testProcess = new TestManagedProcess()) {
underTest.start(() -> testProcess);

testProcess.operational = true;

verify(listener, timeout(1_000L)).onProcessEvent(A_PROCESS_ID, ProcessEventListener.Type.OPERATIONAL);
verify(listener, timeout(1_000L)).onManagedProcessEvent(A_PROCESS_ID, ManagedProcessEventListener.Type.OPERATIONAL);
}
}

@Test
public void test_toString() {
SQProcess underTest = SQProcess.builder(A_PROCESS_ID).build();
ManagedProcessHandler underTest = ManagedProcessHandler.builder(A_PROCESS_ID).build();
assertThat(underTest.toString()).isEqualTo("Process[" + A_PROCESS_ID.getKey() + "]");
}

private static class TestProcess implements ProcessMonitor, AutoCloseable {
private static class TestManagedProcess implements ManagedProcess, AutoCloseable {

private final CountDownLatch alive = new CountDownLatch(1);
private final InputStream inputStream = mock(InputStream.class, Mockito.RETURNS_MOCKS);

server/sonar-main/src/test/java/org/sonar/application/process/LifecycleTest.java → server/sonar-main/src/test/java/org/sonar/application/process/ManagedProcessLifecycleTest.java View File

@@ -28,23 +28,23 @@ import org.sonar.process.ProcessId;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.application.process.Lifecycle.State.INIT;
import static org.sonar.application.process.Lifecycle.State.STARTED;
import static org.sonar.application.process.Lifecycle.State.STARTING;
import static org.sonar.application.process.Lifecycle.State.HARD_STOPPING;
import static org.sonar.application.process.ManagedProcessLifecycle.State.INIT;
import static org.sonar.application.process.ManagedProcessLifecycle.State.STARTED;
import static org.sonar.application.process.ManagedProcessLifecycle.State.STARTING;
import static org.sonar.application.process.ManagedProcessLifecycle.State.HARD_STOPPING;

public class LifecycleTest {
public class ManagedProcessLifecycleTest {

@Test
public void initial_state_is_INIT() {
Lifecycle lifecycle = new Lifecycle(ProcessId.ELASTICSEARCH, Collections.emptyList());
ManagedProcessLifecycle lifecycle = new ManagedProcessLifecycle(ProcessId.ELASTICSEARCH, Collections.emptyList());
assertThat(lifecycle.getState()).isEqualTo(INIT);
}

@Test
public void try_to_move_does_not_support_jumping_states() {
TestLifeCycleListener listener = new TestLifeCycleListener();
Lifecycle lifecycle = new Lifecycle(ProcessId.ELASTICSEARCH, asList(listener));
ManagedProcessLifecycle lifecycle = new ManagedProcessLifecycle(ProcessId.ELASTICSEARCH, asList(listener));
assertThat(lifecycle.getState()).isEqualTo(INIT);
assertThat(listener.states).isEmpty();

@@ -59,14 +59,14 @@ public class LifecycleTest {

@Test
public void no_state_can_not_move_to_itself() {
for (Lifecycle.State state : Lifecycle.State.values()) {
for (ManagedProcessLifecycle.State state : ManagedProcessLifecycle.State.values()) {
assertThat(newLifeCycle(state).tryToMoveTo(state)).isFalse();
}
}

@Test
public void can_move_to_STOPPING_from_STARTING_STARTED_only() {
for (Lifecycle.State state : Lifecycle.State.values()) {
for (ManagedProcessLifecycle.State state : ManagedProcessLifecycle.State.values()) {
TestLifeCycleListener listener = new TestLifeCycleListener();
boolean tryToMoveTo = newLifeCycle(state, listener).tryToMoveTo(HARD_STOPPING);
if (state == STARTING || state == STARTED) {
@@ -81,7 +81,7 @@ public class LifecycleTest {

@Test
public void can_move_to_STARTED_from_STARTING_only() {
for (Lifecycle.State state : Lifecycle.State.values()) {
for (ManagedProcessLifecycle.State state : ManagedProcessLifecycle.State.values()) {
TestLifeCycleListener listener = new TestLifeCycleListener();
boolean tryToMoveTo = newLifeCycle(state, listener).tryToMoveTo(STARTED);
if (state == STARTING) {
@@ -94,15 +94,15 @@ public class LifecycleTest {
}
}

private static Lifecycle newLifeCycle(Lifecycle.State state, TestLifeCycleListener... listeners) {
return new Lifecycle(ProcessId.ELASTICSEARCH, Arrays.asList(listeners), state);
private static ManagedProcessLifecycle newLifeCycle(ManagedProcessLifecycle.State state, TestLifeCycleListener... listeners) {
return new ManagedProcessLifecycle(ProcessId.ELASTICSEARCH, Arrays.asList(listeners), state);
}

private static final class TestLifeCycleListener implements ProcessLifecycleListener {
private final List<Lifecycle.State> states = new ArrayList<>();
private final List<ManagedProcessLifecycle.State> states = new ArrayList<>();

@Override
public void onProcessState(ProcessId processId, Lifecycle.State state) {
public void onProcessState(ProcessId processId, ManagedProcessLifecycle.State state) {
this.states.add(state);
}
}

server/sonar-main/src/test/java/org/sonar/application/process/ProcessCommandsProcessMonitorTest.java → server/sonar-main/src/test/java/org/sonar/application/process/ProcessCommandsManagedProcessTest.java View File

@@ -35,14 +35,14 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


public class ProcessCommandsProcessMonitorTest {
public class ProcessCommandsManagedProcessTest {

@Test
public void ProcessMonitorImpl_is_a_proxy_of_Process() throws Exception {
Process process = mock(Process.class, RETURNS_DEEP_STUBS);
ProcessCommands commands = mock(ProcessCommands.class, RETURNS_DEEP_STUBS);

ProcessCommandsProcessMonitor underTest = new ProcessCommandsProcessMonitor(process, ProcessId.WEB_SERVER, commands);
ProcessCommandsManagedProcess underTest = new ProcessCommandsManagedProcess(process, ProcessId.WEB_SERVER, commands);

underTest.waitFor();
verify(process).waitFor();
@@ -69,7 +69,7 @@ public class ProcessCommandsProcessMonitorTest {
Process process = mock(Process.class, RETURNS_DEEP_STUBS);
ProcessCommands commands = mock(ProcessCommands.class, RETURNS_DEEP_STUBS);

ProcessCommandsProcessMonitor underTest = new ProcessCommandsProcessMonitor(process, null, commands);
ProcessCommandsManagedProcess underTest = new ProcessCommandsManagedProcess(process, null, commands);

underTest.askForHardStop();
verify(commands).askForHardStop();
@@ -90,7 +90,7 @@ public class ProcessCommandsProcessMonitorTest {
Process process = mock(Process.class);
when(process.getInputStream()).thenReturn(null);

ProcessCommandsProcessMonitor underTest = new ProcessCommandsProcessMonitor(process, null, commands);
ProcessCommandsManagedProcess underTest = new ProcessCommandsManagedProcess(process, null, commands);

// no failures
underTest.closeStreams();
@@ -103,7 +103,7 @@ public class ProcessCommandsProcessMonitorTest {
Process process = mock(Process.class);
when(process.getInputStream()).thenReturn(stream);

ProcessCommandsProcessMonitor underTest = new ProcessCommandsProcessMonitor(process, null, mock(ProcessCommands.class, Mockito.RETURNS_MOCKS));
ProcessCommandsManagedProcess underTest = new ProcessCommandsManagedProcess(process, null, mock(ProcessCommands.class, Mockito.RETURNS_MOCKS));

// no failures
underTest.closeStreams();

+ 0
- 4
sonar-application/src/main/java/org/sonar/application/App.java View File

@@ -29,10 +29,6 @@ import org.sonar.application.command.JavaVersion;
import org.sonar.application.config.AppSettings;
import org.sonar.application.config.AppSettingsLoader;
import org.sonar.application.config.AppSettingsLoaderImpl;
import org.sonar.application.process.HardStopRequestWatcherImpl;
import org.sonar.application.process.ProcessLauncher;
import org.sonar.application.process.ProcessLauncherImpl;
import org.sonar.application.process.StopRequestWatcher;
import org.sonar.core.extension.ServiceLoaderWrapper;
import org.sonar.process.System2;
import org.sonar.process.SystemExit;

Loading…
Cancel
Save