Skip to content

Commit

Permalink
Make InternalRuntime not implementor of Runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
sleshchenko committed Apr 6, 2018
1 parent 2f8b464 commit 5ef1775
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
import javax.inject.Singleton;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.runtime.Machine;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;

/** Checks whether runtime is consistent with its configuration. */
@Singleton
class RuntimeConsistencyChecker {
void check(InternalEnvironment environment, DockerInternalRuntime runtime)
throws ValidationException {
throws ValidationException, InfrastructureException {
Map<String, InternalMachineConfig> configs = environment.getMachines();
Map<String, ? extends Machine> machines = runtime.getMachines();
if (configs.size() != machines.size()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class RuntimeConsistencyCheckerTest {

@Test(dataProvider = "consistentRuntimesProvider")
public void consistentRuntimes(InternalEnvironment environment, DockerInternalRuntime runtime)
throws ValidationException {
throws Exception {
new RuntimeConsistencyChecker().check(environment, runtime);
}

Expand All @@ -37,19 +37,19 @@ public void consistentRuntimes(InternalEnvironment environment, DockerInternalRu
expectedExceptions = ValidationException.class
)
public void inconsistentRuntimes(InternalEnvironment environment, DockerInternalRuntime runtime)
throws ValidationException {
throws Exception {
new RuntimeConsistencyChecker().check(environment, runtime);
}

@DataProvider
private static Object[][] consistentRuntimesProvider() {
private static Object[][] consistentRuntimesProvider() throws Exception {
return new Object[][] {
{environment("a", "b"), runtime("b", "a")}, {environment("b", "a"), runtime("b", "a")}
};
}

@DataProvider
private static Object[][] inconsistentRuntimesProvider() {
private static Object[][] inconsistentRuntimesProvider() throws Exception {
return new Object[][] {
{environment("a", "b"), runtime("a")},
{environment("a", "b"), runtime("a", "c")},
Expand All @@ -71,7 +71,7 @@ private static InternalEnvironment environment(String... names) {
return environment;
}

private static DockerInternalRuntime runtime(String... names) {
private static DockerInternalRuntime runtime(String... names) throws Exception {
Map<String, DockerMachine> machines = new HashMap<>();
for (String name : names) {
machines.put(name, mock(DockerMachine.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,6 @@ public WorkspaceImpl getWorkspace(String name, String namespace)
/**
* Gets list of workspaces which user can read
*
* <p>
*
* <p>Returned workspaces have either {@link WorkspaceStatus#STOPPED} status or status defined by
* their runtime instances(if those exist).
*
Expand All @@ -175,7 +173,7 @@ public WorkspaceImpl getWorkspace(String name, String namespace)
* @return the list of workspaces or empty list if user can't read any workspace
* @throws NullPointerException when {@code user} is null
* @throws ServerException when any server error occurs while getting workspaces with {@link
* WorkspaceDao#getWorkspaces(String)}
* WorkspaceDao#getWorkspaces(String, int, long)}
*/
public Page<WorkspaceImpl> getWorkspaces(
String user, boolean includeRuntimes, int maxItems, long skipCount) throws ServerException {
Expand All @@ -201,7 +199,7 @@ public Page<WorkspaceImpl> getWorkspaces(
* @return the list of workspaces or empty list if no matches
* @throws NullPointerException when {@code namespace} is null
* @throws ServerException when any server error occurs while getting workspaces with {@link
* WorkspaceDao#getByNamespace(String)}
* WorkspaceDao#getByNamespace(String, int, long)}
*/
public Page<WorkspaceImpl> getByNamespace(
String namespace, boolean includeRuntimes, int maxItems, long skipCount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,25 @@ public void validate(Environment environment)
*
* @param workspace the workspace to inject runtime into
*/
public void injectRuntime(WorkspaceImpl workspace) {
public void injectRuntime(WorkspaceImpl workspace) throws ServerException {
RuntimeState runtimeState = runtimes.get(workspace.getId());
if (runtimeState != null) {
workspace.setRuntime(new RuntimeImpl(runtimeState.runtime));
try {
workspace.setRuntime(asRuntime(runtimeState));
} catch (InfrastructureException e) {
throw new ServerException(
"Error occurred while runtime state inspection. " + e.getMessage());
}
workspace.setStatus(runtimeState.status);
} else {
workspace.setStatus(STOPPED);
}
}

private RuntimeImpl asRuntime(RuntimeState runtimeState) throws InfrastructureException {
InternalRuntime<?> runtime = runtimeState.runtime;
return new RuntimeImpl(runtime.getActiveEnv(), runtime.getMachines(), runtime.getOwner());
}
/**
* Gets workspace status by its identifier.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,22 @@
import org.eclipse.che.commons.annotation.Nullable;

/**
* Implementation of concrete Runtime
* Implementation of concrete Runtime.
*
* @author gazarenkov
*/
public abstract class InternalRuntime<T extends RuntimeContext> implements Runtime {
public abstract class InternalRuntime<T extends RuntimeContext> {

private final T context;
private final URLRewriter urlRewriter;
private final List<Warning> warnings;
protected WorkspaceStatus status;

/**
* @param context prepared context for runtime starting
* @param urlRewriter url rewriter
* @param warnings warning that occurred while context preparing
*/
public InternalRuntime(T context, URLRewriter urlRewriter, List<Warning> warnings) {
this.context = context;
this.urlRewriter = urlRewriter;
Expand All @@ -49,6 +54,13 @@ public InternalRuntime(T context, URLRewriter urlRewriter, List<Warning> warning
}
}

/**
* @param context prepared context for runtime starting
* @param urlRewriter url rewriter
* @param warnings warning that occurred while context preparing
* @param status status of the runtime, or null if {@link #start(Map)} and {@link #stop(Map)} were
* not invoked yet
*/
public InternalRuntime(
T context,
URLRewriter urlRewriter,
Expand All @@ -63,23 +75,27 @@ public InternalRuntime(
this.status = status;
}

@Override
/** Returns name of the active environment. */
public String getActiveEnv() {
return context.getIdentity().getEnvName();
}

@Override
/** Returns identifier of user who started a runtime. */
public String getOwner() {
return context.getIdentity().getOwnerId();
}

@Override
/** Returns identifier of user who started a runtime. */
public List<? extends Warning> getWarnings() {
return warnings;
}

@Override
public Map<String, ? extends Machine> getMachines() {
/**
* Returns map of machine name to machine instance entries.
*
* @throws InfrastructureException when any error occurs
*/
public Map<String, ? extends Machine> getMachines() throws InfrastructureException {
return getInternalMachines()
.entrySet()
.stream()
Expand All @@ -96,9 +112,12 @@ public List<? extends Warning> getWarnings() {
/**
* Returns map of machine name to machine instance entries.
*
* <p>Implementation should not return null
* <p>Implementation must not return null
*
* @throws InfrastructureException when any error occurs
*/
protected abstract Map<String, ? extends Machine> getInternalMachines();
protected abstract Map<String, ? extends Machine> getInternalMachines()
throws InfrastructureException;

/**
* Returns runtime status.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package org.eclipse.che.api.workspace.server;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
Expand All @@ -31,9 +32,7 @@
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
Expand All @@ -45,8 +44,8 @@
import static org.testng.Assert.assertTrue;
import static org.testng.util.Strings.isNullOrEmpty;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.eclipse.che.account.api.AccountManager;
Expand All @@ -55,26 +54,23 @@
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.Page;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.model.workspace.Runtime;
import org.eclipse.che.api.core.model.workspace.Warning;
import org.eclipse.che.api.core.model.workspace.Workspace;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.api.core.model.workspace.runtime.Machine;
import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineImpl;
import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl;
import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
import org.eclipse.che.api.workspace.server.model.impl.RuntimeImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.InternalRuntime;
import org.eclipse.che.api.workspace.server.spi.RuntimeContext;
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.subject.Subject;
import org.eclipse.che.commons.subject.SubjectImpl;
Expand Down Expand Up @@ -215,7 +211,7 @@ public void getsWorkspacesAvailableForUserWithRuntimes() throws Exception {

final WorkspaceImpl workspace1 = createAndMockWorkspace(config, NAMESPACE_1);
final WorkspaceImpl workspace2 = createAndMockWorkspace(config, NAMESPACE_2);
final TestInternalRuntime runtime2 = mockRuntime(workspace2, RUNNING);
final TestRuntime runtime2 = mockRuntime(workspace2, RUNNING);
when(workspaceDao.getWorkspaces(eq(NAMESPACE_1), anyInt(), anyLong()))
.thenReturn(new Page<>(asList(workspace1, workspace2), 0, 2, 2));

Expand All @@ -232,7 +228,8 @@ public void getsWorkspacesAvailableForUserWithRuntimes() throws Exception {
res2.getStatus(),
RUNNING,
"Workspace status wasn't changed to the runtime instance status");
assertEquals(res2.getRuntime(), runtime2, "Workspace doesn't have expected runtime");
assertEquals(
res2.getRuntime(), new RuntimeImpl(runtime2), "Workspace doesn't have expected runtime");
assertFalse(res2.isTemporary(), "Workspace must be permanent");
}

Expand Down Expand Up @@ -298,7 +295,7 @@ public void getsWorkspacesByNamespaceWithoutRuntimes() throws Exception {
public void getsWorkspacesByNamespaceWithRuntimes() throws Exception {
// given
final WorkspaceImpl workspace = createAndMockWorkspace();
final TestInternalRuntime runtime = mockRuntime(workspace, RUNNING);
final TestRuntime runtime = mockRuntime(workspace, RUNNING);

// when
final Page<WorkspaceImpl> result =
Expand All @@ -312,7 +309,8 @@ public void getsWorkspacesByNamespaceWithRuntimes() throws Exception {
res1.getStatus(),
RUNNING,
"Workspace status wasn't changed to the runtime instance status");
assertEquals(res1.getRuntime(), runtime, "Workspace doesn't have expected runtime");
assertEquals(
res1.getRuntime(), new RuntimeImpl(runtime), "Workspace doesn't have expected runtime");
assertFalse(res1.isTemporary(), "Workspace must be permanent");
}

Expand Down Expand Up @@ -524,30 +522,29 @@ private void mockRuntimeStatus(WorkspaceImpl workspace, WorkspaceStatus status)
when(runtimes.getStatus(workspace.getId())).thenReturn(status);
}

private TestInternalRuntime mockRuntime(WorkspaceImpl workspace, WorkspaceStatus status)
private TestRuntime mockRuntime(WorkspaceImpl workspace, WorkspaceStatus status)
throws Exception {
RuntimeIdentity identity =
new RuntimeIdentityImpl(workspace.getId(), workspace.getConfig().getDefaultEnv(), "id");
// doAnswer(inv -> {
// final WorkspaceImpl ws = (WorkspaceImpl)inv.getArguments()[0];
// ws.setStatus(status);
// return ws;
// }).when(runtimes).injectStatus(workspace);
MachineImpl machine1 = spy(createMachine());
MachineImpl machine2 = spy(createMachine());
Map<String, Machine> machines = new HashMap<>();
machines.put("machine1", machine1);
machines.put("machine2", machine2);
TestInternalRuntime runtime = new TestInternalRuntime(mockContext(identity), machines);
TestRuntime runtime = new TestRuntime(machines);
doAnswer(
inv -> {
workspace.setStatus(status);
workspace.setRuntime(runtime);
workspace.setRuntime(
new RuntimeImpl(
runtime.getActiveEnv(),
runtime.getMachines(),
runtime.getOwner(),
runtime.getWarnings()));
return null;
})
.when(runtimes)
.injectRuntime(workspace);
when(runtimes.isAnyRunning()).thenReturn(true);

return runtime;
}

Expand Down Expand Up @@ -622,40 +619,32 @@ private MachineImpl createMachine() {
return new MachineImpl(emptyMap(), emptyMap(), MachineStatus.RUNNING);
}

private RuntimeContext mockContext(RuntimeIdentity identity) throws Exception {
RuntimeContext context = mock(RuntimeContext.class);
doReturn(context).when(infrastructure).prepare(eq(identity), any(InternalEnvironment.class));
when(context.getInfrastructure()).thenReturn(infrastructure);
when(context.getIdentity()).thenReturn(identity);
return context;
}
private static class TestRuntime implements Runtime {

private static class TestInternalRuntime extends InternalRuntime<RuntimeContext> {
final Map<String, Machine> machines;

TestInternalRuntime(RuntimeContext context, Map<String, Machine> machines) {
super(context, null, null, false);
TestRuntime(Map<String, Machine> machines) {
this.machines = machines;
}

@Override
protected Map<String, Machine> getInternalMachines() {
return machines;
public String getActiveEnv() {
return "default";
}

@Override
public Map<String, String> getProperties() {
return Collections.emptyMap();
public Map<String, ? extends Machine> getMachines() {
return machines;
}

@Override
protected void internalStop(Map stopOptions) throws InfrastructureException {
throw new UnsupportedOperationException();
public String getOwner() {
return "owner";
}

@Override
protected void internalStart(Map startOptions) throws InfrastructureException {
throw new UnsupportedOperationException();
public List<? extends Warning> getWarnings() {
return emptyList();
}
}
}

0 comments on commit 5ef1775

Please sign in to comment.