use of org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException in project che by eclipse.
the class WorkspaceRuntimes method shutdown.
/**
* Terminates workspace runtimes service, so no more workspaces are allowed to start
* or to be stopped directly, all the running workspaces are going to be stopped,
* all the starting tasks will be eventually interrupted.
*
* @throws IllegalStateException
* if component shutdown is already called
*/
public void shutdown() throws InterruptedException {
if (!isShutdown.compareAndSet(false, true)) {
throw new IllegalStateException("Workspace runtimes service shutdown has been already called");
}
List<String> idsToStop;
try (@SuppressWarnings("unused") Unlocker u = locks.writeAllLock()) {
idsToStop = states.entrySet().stream().filter(e -> e.getValue().status != WorkspaceStatus.STOPPING).map(Map.Entry::getKey).collect(Collectors.toList());
states.clear();
}
if (!idsToStop.isEmpty()) {
LOG.info("Shutdown running environments, environments to stop: '{}'", idsToStop.size());
ExecutorService executor = Executors.newFixedThreadPool(2 * Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setNameFormat("StopEnvironmentsPool-%d").setDaemon(false).build());
for (String id : idsToStop) {
executor.execute(() -> {
try {
envEngine.stop(id);
} catch (EnvironmentNotRunningException ignored) {
// might be already stopped
} catch (Exception x) {
LOG.error(x.getMessage(), x);
}
});
}
executor.shutdown();
try {
if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
executor.shutdownNow();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
LOG.error("Unable to stop runtimes termination pool");
}
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
use of org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException in project che by eclipse.
the class CheEnvironmentEngineTest method stopsTheEnvironmentWhileStartOfMachineIsInterrupted.
@Test
public void stopsTheEnvironmentWhileStartOfMachineIsInterrupted() throws Exception {
// given
EnvironmentImpl env = createEnv();
String envName = "env-1";
String workspaceId = "wsId";
int[] counter = new int[] { env.getMachines().size() };
ArrayList<Instance> created = new ArrayList<>();
when(machineProvider.startService(anyString(), eq(workspaceId), eq(envName), anyString(), anyBoolean(), anyString(), any(CheServiceImpl.class), any(LineConsumer.class))).thenAnswer(invocationOnMock -> {
if (--counter[0] == 0) {
Thread.currentThread().interrupt();
throw new ServerException("interrupted!");
}
Object[] arguments = invocationOnMock.getArguments();
NoOpMachineInstance instance = spy(new NoOpMachineInstance(createMachine(workspaceId, envName, (CheServiceImpl) arguments[6], (String) arguments[3], (boolean) arguments[4])));
created.add(instance);
return instance;
});
when(environmentParser.parse(env)).thenReturn(createCheServicesEnv());
// when, then
try {
engine.start(workspaceId, envName, env, false, messageConsumer, startedHandler);
fail("environment must not be running");
} catch (EnvironmentStartInterruptedException x) {
assertEquals(x.getMessage(), format("Start of environment '%s' in workspace '%s' is interrupted", envName, workspaceId));
}
// environment must not be running
try {
engine.getMachines(workspaceId);
fail("environment must not be running");
} catch (EnvironmentNotRunningException x) {
assertEquals(x.getMessage(), format("Environment with ID '%s' is not found", workspaceId));
}
// all the machines expect of the last one must be destroyed
for (Instance instance : created) {
verify(instance).destroy();
}
}
use of org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException in project che by eclipse.
the class WorkspaceRuntimesTest method stopsTheRunningWorkspaceAndRethrowsTheErrorDifferentFromServerException.
@Test
public void stopsTheRunningWorkspaceAndRethrowsTheErrorDifferentFromServerException() throws Exception {
setRuntime("workspace", WorkspaceStatus.RUNNING);
doThrow(new EnvironmentNotRunningException("no!")).when(envEngine).stop("workspace");
try {
runtimes.stop("workspace");
} catch (ServerException x) {
assertEquals(x.getMessage(), "no!");
assertTrue(x.getCause() instanceof EnvironmentNotRunningException);
}
verify(envEngine).stop("workspace");
assertFalse(runtimeStates.containsKey("workspace"));
verifyEventsSequence(event("workspace", WorkspaceStatus.RUNNING, WorkspaceStatus.STOPPING, EventType.STOPPING, null), event("workspace", WorkspaceStatus.STOPPING, WorkspaceStatus.STOPPED, EventType.ERROR, "no!"));
}
use of org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException in project che by eclipse.
the class CheEnvironmentEngine method startMachine.
/**
* Starts machine in running environment.
*
* @param workspaceId
* ID of workspace that owns environment in which machine should be started
* @param machineConfig
* configuration of machine that should be started
* @return running machine
* @throws EnvironmentNotRunningException
* if environment is not running
* @throws NotFoundException
* if provider of machine implementation is not found
* @throws ConflictException
* if machine with the same name already exists in the environment
* @throws ServerException
* if any other error occurs
*/
public Instance startMachine(String workspaceId, MachineConfig machineConfig, List<String> agents) throws ServerException, NotFoundException, ConflictException, EnvironmentException {
MachineConfig machineConfigCopy = new MachineConfigImpl(machineConfig);
EnvironmentHolder environmentHolder;
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.readLock(workspaceId)) {
environmentHolder = environments.get(workspaceId);
if (environmentHolder == null || environmentHolder.status != EnvStatus.RUNNING) {
throw new EnvironmentNotRunningException(format("Environment '%s' is not running", workspaceId));
}
for (Instance machine : environmentHolder.machines) {
if (machine.getConfig().getName().equals(machineConfigCopy.getName())) {
throw new ConflictException(format("Machine with name '%s' already exists in environment of workspace '%s'", machineConfigCopy.getName(), workspaceId));
}
}
}
final String creator = EnvironmentContext.getCurrent().getSubject().getUserId();
final String namespace = EnvironmentContext.getCurrent().getSubject().getUserName();
MachineImpl machine = MachineImpl.builder().setConfig(machineConfig).setWorkspaceId(workspaceId).setStatus(MachineStatus.CREATING).setEnvName(environmentHolder.name).setOwner(creator).build();
MachineStarter machineStarter;
if ("docker".equals(machineConfig.getType())) {
// needed to reuse startInstance method and
// create machine instances by different implementation-specific providers
CheServiceImpl service = machineConfigToService(machineConfig);
normalize(namespace, workspaceId, machineConfig.getName(), service);
machine.setId(service.getId());
machineStarter = (machineLogger, machineSource) -> {
CheServiceImpl serviceWithNormalizedSource = normalizeServiceSource(service, machineSource);
normalize(namespace, workspaceId, machineConfig.getName(), serviceWithNormalizedSource);
infrastructureProvisioner.provision(new ExtendedMachineImpl().withAgents(agents), serviceWithNormalizedSource);
return machineProvider.startService(namespace, workspaceId, environmentHolder.name, machineConfig.getName(), machineConfig.isDev(), environmentHolder.networkId, serviceWithNormalizedSource, machineLogger);
};
} else {
try {
InstanceProvider provider = machineInstanceProviders.getProvider(machineConfig.getType());
machine.setId(generateMachineId());
addAgentsProvidedServers(machine, agents);
machineStarter = (machineLogger, machineSource) -> {
Machine machineWithNormalizedSource = normalizeMachineSource(machine, machineSource);
return provider.createInstance(machineWithNormalizedSource, machineLogger);
};
} catch (NotFoundException e) {
throw new NotFoundException(format("Provider of machine type '%s' not found", machineConfig.getType()));
}
}
return startInstance(false, environmentHolder.logger, machine, machineStarter);
}
use of org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException in project che by eclipse.
the class CheEnvironmentEngine method stop.
/**
* Stops running environment of specified workspace.
*
* @param workspaceId
* ID of workspace that owns environment
* @throws EnvironmentNotRunningException
* when environment is not running
* @throws ServerException
* if other error occurs
*/
public void stop(String workspaceId) throws EnvironmentNotRunningException, ServerException {
List<Instance> machinesCopy;
EnvironmentHolder environmentHolder;
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.readLock(workspaceId)) {
environmentHolder = environments.get(workspaceId);
if (environmentHolder == null || environmentHolder.status != EnvStatus.RUNNING) {
throw new EnvironmentNotRunningException(format("Stop of not running environment of workspace with ID '%s' is not allowed.", workspaceId));
}
List<Instance> machines = environmentHolder.machines;
if (machines != null && !machines.isEmpty()) {
machinesCopy = new ArrayList<>(machines);
} else {
machinesCopy = emptyList();
}
}
// long operation - perform out of lock
destroyEnvironment(environmentHolder.networkId, machinesCopy);
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.writeLock(workspaceId)) {
environments.remove(workspaceId);
}
}
Aggregations