diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index 651610b92c..ac00000549 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -291,10 +291,6 @@ org.eclipse.che.multiuser che-multiuser-permission-devfile - - org.eclipse.che.multiuser - che-multiuser-permission-factory - org.eclipse.che.multiuser che-multiuser-permission-logger diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index 88ddc7aae8..c299020834 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -358,7 +358,6 @@ public class WsMasterModule extends AbstractModule { bind(org.eclipse.che.multiuser.permission.user.UserServicePermissionsFilter.class); bind(org.eclipse.che.multiuser.permission.logger.LoggerServicePermissionsFilter.class); - bind(org.eclipse.che.multiuser.permission.factory.FactoryPermissionsFilter.class); bind(org.eclipse.che.multiuser.permission.devfile.DevfilePermissionsFilter.class); bind(org.eclipse.che.multiuser.permission.workspace.activity.ActivityPermissionsFilter.class); bind(AdminPermissionInitializer.class).asEagerSingleton(); diff --git a/multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineAuthModule.java b/multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineAuthModule.java index 4a3826dbe2..34fc93383f 100644 --- a/multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineAuthModule.java +++ b/multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineAuthModule.java @@ -52,14 +52,7 @@ public class MachineAuthModule extends AbstractModule { .addBinding() .toInstance( new MachineAuthenticatedResource( - "/workspace", - "getByKey", - "addProject", - "updateProject", - "deleteProject", - "getSettings", - "update", - "stop")); + "/workspace", "getByKey", "getSettings", "update", "stop")); machineAuthenticatedResources .addBinding() .toInstance( @@ -67,13 +60,7 @@ public class MachineAuthModule extends AbstractModule { "/ssh", "getPair", "generatePair", "createPair", "getPairs", "removePair")); machineAuthenticatedResources .addBinding() - .toInstance( - new MachineAuthenticatedResource( - "/factory", - "getFactoryJson", - "getFactory", - "getFactoryByAttribute", - "resolveFactory")); + .toInstance(new MachineAuthenticatedResource("/factory", "resolveFactory")); machineAuthenticatedResources .addBinding() .toInstance( diff --git a/multiuser/machine-auth/che-multiuser-machine-authentication/src/test/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenAccessFilterTest.java b/multiuser/machine-auth/che-multiuser-machine-authentication/src/test/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenAccessFilterTest.java index 2fa2a4c726..dab5b75415 100644 --- a/multiuser/machine-auth/che-multiuser-machine-authentication/src/test/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenAccessFilterTest.java +++ b/multiuser/machine-auth/che-multiuser-machine-authentication/src/test/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenAccessFilterTest.java @@ -19,7 +19,6 @@ import java.lang.reflect.Method; import java.util.Collections; import org.eclipse.che.api.core.ForbiddenException; import org.eclipse.che.api.workspace.server.WorkspaceService; -import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; import org.eclipse.che.commons.env.EnvironmentContext; import org.eclipse.che.multiuser.api.permission.server.AuthorizedSubject; import org.everrest.core.impl.resource.PathValue; @@ -48,9 +47,7 @@ public class MachineTokenAccessFilterTest { private void setUp() { filter = new MachineTokenAccessFilter( - Collections.singleton( - new MachineAuthenticatedResource( - "/workspace", "getByKey", "addProject", "updateProject", "deleteProject"))); + Collections.singleton(new MachineAuthenticatedResource("/workspace", "getByKey"))); } @Test @@ -61,22 +58,6 @@ public class MachineTokenAccessFilterTest { verifyZeroInteractions(genericMethodResource); } - @Test - public void shouldNotLimitAccessIfMethodIsAllowed() throws Exception { - when(environmentContext.getSubject()).thenReturn(machineTokenAuthorizedSubject); - EnvironmentContext.setCurrent(environmentContext); - Method method = - WorkspaceService.class.getMethod( - "updateProject", String.class, String.class, ProjectConfigDto.class); - ResourceDescriptor descriptor = mock(ResourceDescriptor.class); - PathValue pathValue = mock(PathValue.class); - when(genericMethodResource.getMethod()).thenReturn(method); - when(descriptor.getPathValue()).thenReturn(pathValue); - when(genericMethodResource.getParentResource()).thenReturn(descriptor); - when(pathValue.getPath()).thenReturn("/workspace"); - filter.filter(genericMethodResource, new Object[] {}); - } - @Test(expectedExceptions = ForbiddenException.class) public void shouldLimitAccessIfMethodIsNotAllowed() throws Exception { when(environmentContext.getSubject()).thenReturn(machineTokenAuthorizedSubject); diff --git a/multiuser/permission/che-multiuser-permission-factory/src/test/java/org/eclipse/che/multiuser/permission/factory/FactoryPermissionsFilterTest.java b/multiuser/permission/che-multiuser-permission-factory/src/test/java/org/eclipse/che/multiuser/permission/factory/FactoryPermissionsFilterTest.java index 8a8e3d6889..dbf64736e0 100644 --- a/multiuser/permission/che-multiuser-permission-factory/src/test/java/org/eclipse/che/multiuser/permission/factory/FactoryPermissionsFilterTest.java +++ b/multiuser/permission/che-multiuser-permission-factory/src/test/java/org/eclipse/che/multiuser/permission/factory/FactoryPermissionsFilterTest.java @@ -72,117 +72,6 @@ public class FactoryPermissionsFilterTest { @InjectMocks private FactoryPermissionsFilter permissionsFilter; - @Test - public void shouldCheckPermissionsOnGettingFactoryJsonByWorkspaceId() throws Exception { - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .get(SECURE_PATH + "/factory/workspace/workspace123"); - - assertEquals(response.getStatusCode(), 204); - verify(service).getFactoryJson(eq("workspace123"), nullable(String.class)); - verify(subject).checkPermission(DOMAIN_ID, "workspace123", READ); - } - - @Test - public void shouldReturnForbiddenWhenUserDoesHavePermissionsToReadWorkspaceOnGettingFactoryJson() - throws Exception { - doThrow(new ForbiddenException("User in not authorized")) - .when(subject) - .checkPermission(anyString(), anyString(), anyString()); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .get(SECURE_PATH + "/factory/workspace/workspace123"); - - assertEquals(response.getStatusCode(), 403); - } - - @Test - public void shouldMakeSureThatUserIsCreatorOnUpdatingFactory() throws Exception { - doReturn("user123").when(subject).getUserId(); - - Factory factory = mock(Factory.class); - doReturn(new AuthorImpl("user123", 12345L)).when(factory).getCreator(); - when(factoryManager.getById("factory123")).thenReturn(factory); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(DtoFactory.newDto(FactoryDto.class)) - .when() - .put(SECURE_PATH + "/factory/factory123"); - - assertEquals(response.getStatusCode(), 204); - verify(service).updateFactory(eq("factory123"), any(FactoryDto.class)); - } - - @Test - public void shouldReturnForbiddenWhenUserIsNotCreatorOnUpdatingFactory() throws Exception { - doReturn("user321").when(subject).getUserId(); - - Factory factory = mock(Factory.class); - doReturn(new AuthorImpl("user123", 12345L)).when(factory).getCreator(); - when(factoryManager.getById("factory123")).thenReturn(factory); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(DtoFactory.newDto(FactoryDto.class)) - .when() - .put(SECURE_PATH + "/factory/factory123"); - - assertEquals(response.getStatusCode(), 403); - verify(service, never()).updateFactory(any(), any()); - } - - @Test - public void shouldMakeSureThatUserIsCreatorOnRemovingFactory() throws Exception { - doReturn("user123").when(subject).getUserId(); - - Factory factory = mock(Factory.class); - doReturn(new AuthorImpl("user123", 12345L)).when(factory).getCreator(); - when(factoryManager.getById("factory123")).thenReturn(factory); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .delete(SECURE_PATH + "/factory/factory123"); - - assertEquals(response.getStatusCode(), 204); - verify(service).removeFactory(eq("factory123")); - } - - @Test - public void shouldReturnForbiddenWhenUserIsNotCreatorOnRemovingForeignFactory() throws Exception { - doReturn("user321").when(subject).getUserId(); - - Factory factory = mock(Factory.class); - doReturn(new AuthorImpl("user123", 12345L)).when(factory).getCreator(); - when(factoryManager.getById("factory123")).thenReturn(factory); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .delete(SECURE_PATH + "/factory/factory123"); - - assertEquals(response.getStatusCode(), 403); - verify(service, never()).removeFactory(any()); - } - @Test(dataProvider = "publicMethods") public void shouldDoNothingWhenPublicMethodMethodIsCalled(String name, Class[] parameterTypes) throws Exception { @@ -196,10 +85,8 @@ public class FactoryPermissionsFilterTest { @DataProvider(name = "publicMethods") public Object[][] publicMethods() { return new Object[][] { - {"saveFactory", new Class[] {FactoryDto.class}}, - {"getFactory", new Class[] {String.class, Boolean.class}}, + {"resolveFactory", new Class[] {Map.class, Boolean.class}}, - {"getFactoryByAttribute", new Class[] {Integer.class, Integer.class, UriInfo.class}}, }; } diff --git a/multiuser/permission/che-multiuser-permission-workspace/src/main/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilter.java b/multiuser/permission/che-multiuser-permission-workspace/src/main/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilter.java index cb91f447da..825d8efaa0 100644 --- a/multiuser/permission/che-multiuser-permission-workspace/src/main/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilter.java +++ b/multiuser/permission/che-multiuser-permission-workspace/src/main/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilter.java @@ -101,12 +101,6 @@ public class WorkspacePermissionsFilter extends CheMethodInvokerFilter { return; } - case "startFromConfig": - { - checkAccountPermissions((String) arguments[2], AccountOperation.CREATE_WORKSPACE); - return; - } - case "delete": key = ((String) arguments[0]); action = DELETE; @@ -126,22 +120,11 @@ public class WorkspacePermissionsFilter extends CheMethodInvokerFilter { if (superPrivilegesChecker.hasSuperPrivileges()) { return; } - // fall through - case "checkAgentHealth": key = ((String) arguments[0]); action = READ; break; case "update": - case "addProject": - case "deleteProject": - case "updateProject": - case "addEnvironment": - case "deleteEnvironment": - case "updateEnvironment": - case "addCommand": - case "deleteCommand": - case "updateCommand": key = ((String) arguments[0]); action = CONFIGURE; break; diff --git a/multiuser/permission/che-multiuser-permission-workspace/src/test/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilterTest.java b/multiuser/permission/che-multiuser-permission-workspace/src/test/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilterTest.java index 286f2db51b..570c61ad30 100644 --- a/multiuser/permission/che-multiuser-permission-workspace/src/test/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilterTest.java +++ b/multiuser/permission/che-multiuser-permission-workspace/src/test/java/org/eclipse/che/multiuser/permission/workspace/server/filters/WorkspacePermissionsFilterTest.java @@ -45,8 +45,6 @@ import org.eclipse.che.api.core.rest.shared.dto.ServiceError; import org.eclipse.che.api.workspace.server.WorkspaceManager; import org.eclipse.che.api.workspace.server.WorkspaceService; import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl; -import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto; -import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto; import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto; import org.eclipse.che.commons.env.EnvironmentContext; import org.eclipse.che.commons.subject.Subject; @@ -125,26 +123,6 @@ public class WorkspacePermissionsFilterTest { .checkAccountPermissions(anyString(), any()); } - @Test - public void shouldCheckAccountPermissionsAccessOnWorkspaceCreationFromConfig() throws Exception { - doNothing().when(permissionsFilter).checkAccountPermissions(anyString(), any()); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(DtoFactory.newDto(WorkspaceConfigDto.class)) - .when() - .post(SECURE_PATH + "/workspace?namespace=userok"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService) - .create(any(WorkspaceConfigDto.class), any(), any(), any(), eq("userok")); - verify(permissionsFilter).checkAccountPermissions("userok", AccountOperation.CREATE_WORKSPACE); - verifyZeroInteractions(subject); - } - @Test public void shouldCheckAccountPermissionsAccessOnWorkspaceCreationFromDevfile() throws Exception { doNothing().when(permissionsFilter).checkAccountPermissions(anyString(), any()); @@ -208,24 +186,6 @@ public class WorkspacePermissionsFilterTest { verifyZeroInteractions(subject); } - @Test - public void shouldCheckAccountPermissionsOnStartingWorkspaceFromConfig() throws Exception { - doNothing().when(permissionsFilter).checkAccountPermissions(anyString(), any()); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .when() - .post(SECURE_PATH + "/workspace/runtime?namespace=userok"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).startFromConfig(any(), any(), eq("userok")); - verify(permissionsFilter).checkAccountPermissions("userok", AccountOperation.CREATE_WORKSPACE); - verifyZeroInteractions(subject); - } - @Test public void shouldNotCheckPermissionsOnGettingSettings() throws Exception { final Response response = @@ -382,163 +342,6 @@ public class WorkspacePermissionsFilterTest { verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("read")); } - @Test - public void shouldCheckPermissionsOnProjectAdding() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .contentType("application/json") - .when() - .post(SECURE_PATH + "/workspace/{id}/project"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).addProject(eq("workspace123"), any()); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnProjectRemoving() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .when() - .delete(SECURE_PATH + "/workspace/{id}/project/spring"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).deleteProject(eq("workspace123"), eq("spring")); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnProjectUpdating() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .when() - .put(SECURE_PATH + "/workspace/{id}/project/spring"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).updateProject(eq("workspace123"), eq("spring"), any()); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnCommandAdding() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .pathParam("id", "workspace123") - .when() - .post(SECURE_PATH + "/workspace/{id}/command"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).addCommand(eq("workspace123"), any()); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnCommandRemoving() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .when() - .delete(SECURE_PATH + "/workspace/{id}/command/run-application"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).deleteCommand(eq("workspace123"), eq("run-application")); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnCommandUpdating() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .when() - .put(SECURE_PATH + "/workspace/{id}/command/run-application"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).updateCommand(eq("workspace123"), eq("run-application"), any()); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnEnvironmentAdding() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .contentType("application/json") - .when() - .post(SECURE_PATH + "/workspace/{id}/environment"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService) - .addEnvironment(eq("workspace123"), nullable(EnvironmentDto.class), nullable(String.class)); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnEnvironmentRemoving() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .when() - .delete(SECURE_PATH + "/workspace/{id}/environment/ubuntu"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).deleteEnvironment(eq("workspace123"), eq("ubuntu")); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - - @Test - public void shouldCheckPermissionsOnEnvironmentUpdating() throws Exception { - when(subject.hasPermission("workspace", "workspace123", "configure")).thenReturn(true); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .pathParam("id", "workspace123") - .when() - .put(SECURE_PATH + "/workspace/{id}/environment/ubuntu"); - - assertEquals(response.getStatusCode(), 204); - verify(workspaceService).updateEnvironment(eq("workspace123"), eq("ubuntu"), any()); - verify(subject).hasPermission(eq("workspace"), eq("workspace123"), eq("configure")); - } - @Test( expectedExceptions = ForbiddenException.class, expectedExceptionsMessageRegExp = @@ -632,18 +435,8 @@ public class WorkspacePermissionsFilterTest { public Object[][] pathsProvider() { return new Object[][] { {"/workspace/workspace123", "get", WorkspaceDomain.READ}, - {"/workspace/workspace123", "put", WorkspaceDomain.CONFIGURE}, {"/workspace/workspace123/runtime", "post", WorkspaceDomain.RUN}, {"/workspace/workspace123/runtime", "delete", WorkspaceDomain.RUN}, - {"/workspace/workspace123/command", "post", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/command/run-application", "put", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/command/run-application", "delete", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/environment", "post", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/environment/myEnvironment", "put", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/environment/myEnvironment", "delete", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/project", "post", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/project/spring", "put", WorkspaceDomain.CONFIGURE}, - {"/workspace/workspace123/project/spring", "delete", WorkspaceDomain.CONFIGURE}, }; } diff --git a/multiuser/permission/pom.xml b/multiuser/permission/pom.xml index bc4473de3f..08cd55e0ba 100644 --- a/multiuser/permission/pom.xml +++ b/multiuser/permission/pom.xml @@ -28,7 +28,6 @@ che-multiuser-permission-devfile che-multiuser-permission-workspace che-multiuser-permission-workspace-activity - che-multiuser-permission-factory che-multiuser-permission-system che-multiuser-permission-resource che-multiuser-permission-logger diff --git a/pom.xml b/pom.xml index 46a1d34e78..00331b2d36 100644 --- a/pom.xml +++ b/pom.xml @@ -1115,11 +1115,6 @@ che-multiuser-permission-devfile ${che.version} - - org.eclipse.che.multiuser - che-multiuser-permission-factory - ${che.version} - org.eclipse.che.multiuser che-multiuser-permission-logger diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java index c97aefa46a..452b9982bb 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java @@ -11,13 +11,9 @@ */ package org.eclipse.che.api.factory.server; -import static java.lang.Boolean.parseBoolean; -import static java.util.stream.Collectors.toList; -import static javax.ws.rs.core.HttpHeaders.CONTENT_DISPOSITION; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static org.eclipse.che.api.factory.server.FactoryLinksHelper.createLinks; -import com.google.common.collect.ImmutableSet; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -26,48 +22,21 @@ import io.swagger.annotations.ApiResponses; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Predicate; import javax.inject.Inject; import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; import javax.ws.rs.POST; -import javax.ws.rs.PUT; import javax.ws.rs.Path; -import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; -import org.eclipse.che.api.core.ConflictException; -import org.eclipse.che.api.core.ForbiddenException; -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.factory.Factory; -import org.eclipse.che.api.core.model.user.User; -import org.eclipse.che.api.core.model.workspace.config.ProjectConfig; import org.eclipse.che.api.core.rest.Service; -import org.eclipse.che.api.factory.server.builder.FactoryBuilder; -import org.eclipse.che.api.factory.shared.dto.AuthorDto; import org.eclipse.che.api.factory.shared.dto.FactoryDto; -import org.eclipse.che.api.user.server.PreferenceManager; import org.eclipse.che.api.user.server.UserManager; -import org.eclipse.che.api.workspace.server.WorkspaceManager; -import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl; -import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl; -import org.eclipse.che.commons.env.EnvironmentContext; -import org.eclipse.che.commons.lang.Pair; -import org.eclipse.che.commons.lang.URLEncodedUtils; -import org.eclipse.che.dto.server.DtoFactory; /** * Defines Factory REST API. @@ -86,231 +55,20 @@ public class FactoryService extends Service { /** Validate query parameter. If true, factory will be validated */ public static final String VALIDATE_QUERY_PARAMETER = "validate"; - private final FactoryManager factoryManager; private final UserManager userManager; - private final PreferenceManager preferenceManager; - private final FactoryEditValidator editValidator; - private final FactoryCreateValidator createValidator; private final FactoryAcceptValidator acceptValidator; - private final FactoryBuilder factoryBuilder; - private final WorkspaceManager workspaceManager; private final FactoryParametersResolverHolder factoryParametersResolverHolder; @Inject public FactoryService( - FactoryManager factoryManager, UserManager userManager, - PreferenceManager preferenceManager, - FactoryCreateValidator createValidator, FactoryAcceptValidator acceptValidator, - FactoryEditValidator editValidator, - FactoryBuilder factoryBuilder, - WorkspaceManager workspaceManager, FactoryParametersResolverHolder factoryParametersResolverHolder) { - this.factoryManager = factoryManager; this.userManager = userManager; - this.createValidator = createValidator; - this.preferenceManager = preferenceManager; this.acceptValidator = acceptValidator; - this.editValidator = editValidator; - this.factoryBuilder = factoryBuilder; - this.workspaceManager = workspaceManager; this.factoryParametersResolverHolder = factoryParametersResolverHolder; } - @POST - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation(value = "Create a new factory based on configuration") - @ApiResponses({ - @ApiResponse(code = 200, message = "Factory successfully created"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "User does not have rights to create factory"), - @ApiResponse(code = 409, message = "When factory with given name and creator already exists"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public FactoryDto saveFactory(FactoryDto factory) - throws BadRequestException, ServerException, ForbiddenException, ConflictException, - NotFoundException { - requiredNotNull(factory, "Factory configuration"); - factoryBuilder.checkValid(factory); - processDefaults(factory); - createValidator.validateOnCreate(factory); - return injectLinks(asDto(factoryManager.saveFactory(factory))); - } - - @GET - @Path("/{id}") - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Get factory by its identifier", - notes = "If validate parameter is not specified, retrieved factory wont be validated") - @ApiResponses({ - @ApiResponse(code = 200, message = "Response contains requested factory entry"), - @ApiResponse(code = 400, message = "Missed required parameters, failed to validate factory"), - @ApiResponse(code = 404, message = "Factory with specified identifier does not exist"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public FactoryDto getFactory( - @ApiParam(value = "Factory identifier") @PathParam("id") String factoryId, - @ApiParam( - value = - "Whether or not to validate values like it is done when accepting the factory", - allowableValues = "true, false", - defaultValue = "false") - @DefaultValue("false") - @QueryParam("validate") - Boolean validate) - throws BadRequestException, NotFoundException, ServerException { - final FactoryDto factoryDto = asDto(factoryManager.getById(factoryId)); - if (validate) { - acceptValidator.validateOnAccept(factoryDto); - } - return injectLinks(factoryDto); - } - - @GET - @Path("/find") - @Produces(APPLICATION_JSON) - @ApiOperation( - value = - "Get factory by attribute, " - + "the attribute must match one of the Factory model fields with type 'String', " - + "e.g. (factory.name, factory.creator.name)" - + " This method is going to be deprecated or limited in scope in 6.0 GA " - + "since it's not optimized on backend performance. " - + "Expected parameters creator.userId=? or name=?.", - notes = - "If specify more than one value for a single query parameter then will be taken the first one") - @ApiResponses({ - @ApiResponse(code = 200, message = "Response contains list requested factories"), - @ApiResponse( - code = 400, - message = "When query does not contain at least one attribute to search for"), - @ApiResponse(code = 500, message = "Internal server error") - }) - @Deprecated - public Response getFactoryByAttribute( - @DefaultValue("0") @QueryParam("skipCount") Integer skipCount, - @DefaultValue("30") @QueryParam("maxItems") Integer maxItems, - @Context UriInfo uriInfo) - throws BadRequestException, ServerException { - final Set skip = ImmutableSet.of("token", "skipCount", "maxItems"); - final List> query = - URLEncodedUtils.parse(uriInfo.getRequestUri()) - .entrySet() - .stream() - .filter(param -> !skip.contains(param.getKey()) && !param.getValue().isEmpty()) - .map(entry -> Pair.of(entry.getKey(), entry.getValue().iterator().next())) - .collect(toList()); - checkArgument(!query.isEmpty(), "Query must contain at least one attribute"); - - for (Pair pair : query) { - if (!pair.first.equals("creator.userId") && !pair.first.equals("name")) { - throw new BadRequestException( - String.format( - "Method factory.find is going to be removed or limited in scope in 6.0 GA." - + " Search allowed only by creator.userId and name parameters." - + " Requested attributes %s, skipCount %s, maxItems %s", - query, skip, maxItems)); - } - } - - Page factoriesPage = - factoryManager.getByAttribute(maxItems, skipCount, query); - List list = new ArrayList<>(); - for (Factory factory : factoriesPage.getItems()) { - list.add(injectLinks(asDto(factory))); - } - return Response.ok().entity(list).header("Link", createLinkHeader(factoriesPage)).build(); - } - - @PUT - @Path("/{id}") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Update factory information by configuration and specified identifier", - notes = - "Update factory based on the factory id which is passed in a path parameter. " - + "For perform this operation user needs respective rights") - @ApiResponses({ - @ApiResponse(code = 200, message = "Factory successfully updated"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "User does not have rights to update factory"), - @ApiResponse(code = 404, message = "Factory to update not found"), - @ApiResponse( - code = 409, - message = - "Conflict error occurred during factory update" - + "(e.g. Factory with such name and creator already exists)"), - @ApiResponse(code = 500, message = "Internal server error") - }) - public FactoryDto updateFactory( - @ApiParam(value = "Factory identifier") @PathParam("id") String factoryId, FactoryDto update) - throws BadRequestException, NotFoundException, ServerException, ForbiddenException, - ConflictException { - requiredNotNull(update, "Factory configuration"); - update.setId(factoryId); - final Factory existing = factoryManager.getById(factoryId); - // check if the current user has enough access to edit the factory - editValidator.validate(existing); - factoryBuilder.checkValid(update, true); - // validate the new content - createValidator.validateOnCreate(update); - return injectLinks(asDto(factoryManager.updateFactory(update))); - } - - @DELETE - @Path("/{id}") - @ApiOperation( - value = "Removes factory by its identifier", - notes = - "Removes factory based on the factory id which is passed in a path parameter. " - + "For perform this operation user needs respective rights") - @ApiResponses({ - @ApiResponse(code = 200, message = "Factory successfully removed"), - @ApiResponse(code = 403, message = "User not authorized to call this operation"), - @ApiResponse(code = 404, message = "Factory not found"), - @ApiResponse(code = 500, message = "Internal server error") - }) - public void removeFactory(@ApiParam(value = "Factory identifier") @PathParam("id") String id) - throws ServerException { - factoryManager.removeFactory(id); - } - - @GET - @Path("/workspace/{ws-id}") - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Construct factory from workspace", - notes = "This call returns a Factory.json that is used to create a factory") - @ApiResponses({ - @ApiResponse(code = 200, message = "Response contains requested factory JSON"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 404, message = "Workspace not found"), - @ApiResponse(code = 409, message = "Workspace can not be exported as factory"), - @ApiResponse(code = 500, message = "Internal server error") - }) - public Response getFactoryJson( - @ApiParam(value = "Workspace identifier") @PathParam("ws-id") String wsId, - @ApiParam(value = "Project path") @QueryParam("path") String path) - throws BadRequestException, NotFoundException, ServerException, ConflictException { - final WorkspaceImpl workspace = workspaceManager.getWorkspace(wsId); - if (workspace.getConfig() == null) { - throw new ConflictException("Workspace created with Devfile can not be exported as Factory."); - } - excludeProjectsWithoutLocation(workspace, path); - final FactoryDto factoryDto = - DtoFactory.newDto(FactoryDto.class) - .withV("4.0") - .withWorkspace( - org.eclipse.che.api.workspace.server.DtoConverter.asDto(workspace.getConfig())); - return Response.ok(factoryDto, APPLICATION_JSON) - .header(CONTENT_DISPOSITION, "attachment; filename=factory.json") - .build(); - } - @POST @Path("/resolver") @Consumes(APPLICATION_JSON) @@ -364,69 +122,6 @@ public class FactoryService extends Service { return factory.withLinks(createLinks(factory, getServiceContext(), username)); } - /** - * Filters workspace projects and removes projects without source location. If there is no at - * least one project with source location then {@link BadRequestException} will be thrown - */ - private static void excludeProjectsWithoutLocation( - WorkspaceImpl usersWorkspace, String projectPath) throws BadRequestException { - final boolean notEmptyPath = projectPath != null; - // Condition for sifting valid project in user's workspace - Predicate predicate = - projectConfig -> { - // if project is a sub project (it's path contains another project) , then location can be - // null - final boolean isSubProject = projectConfig.getPath().indexOf('/', 1) != -1; - final boolean hasNotEmptySource = - projectConfig.getSource() != null - && projectConfig.getSource().getType() != null - && projectConfig.getSource().getLocation() != null; - - return !(notEmptyPath && !projectPath.equals(projectConfig.getPath())) - && (isSubProject || hasNotEmptySource); - }; - - // Filtered out projects by path and source storage presence - final List filtered = - usersWorkspace.getConfig().getProjects().stream().filter(predicate).collect(toList()); - checkArgument( - !filtered.isEmpty(), - "Unable to create factory from this workspace, " - + "because it does not contains projects with source storage"); - usersWorkspace.getConfig().setProjects(filtered); - } - - /** - * Checks the current user if it is not temporary then adds to the factory creator information and - * time of creation - */ - private void processDefaults(FactoryDto factory) throws ForbiddenException { - try { - final String userId = EnvironmentContext.getCurrent().getSubject().getUserId(); - final User user = userManager.getById(userId); - if (user == null || parseBoolean(preferenceManager.find(userId).get("temporary"))) { - throw new ForbiddenException("Current user is not allowed to use this method."); - } - factory.setCreator( - DtoFactory.newDto(AuthorDto.class) - .withUserId(userId) - .withName(user.getName()) - .withEmail(user.getEmail()) - .withCreated(System.currentTimeMillis())); - } catch (NotFoundException | ServerException ex) { - throw new ForbiddenException("Current user is not allowed to use this method"); - } - } - - /** Converts {@link Factory} to dto object */ - private FactoryDto asDto(Factory factory) throws ServerException { - try { - return DtoConverter.asDto(factory, userManager.getById(factory.getCreator().getUserId())); - } catch (ServerException | NotFoundException ex) { - throw new ServerException("Failed to retrieve factory creator"); - } - } - /** Usage of a dedicated class to manage the optional service-specific resolvers */ protected static class FactoryParametersResolverHolder { diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java index d6300f648f..fc32d51d5e 100644 --- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java +++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java @@ -12,15 +12,10 @@ package org.eclipse.che.api.factory.server; import static com.jayway.restassured.RestAssured.given; -import static java.lang.String.format; import static java.lang.String.valueOf; -import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; -import static java.util.stream.Collectors.toSet; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.Response.Status.BAD_REQUEST; -import static org.eclipse.che.api.factory.server.DtoConverter.asDto; import static org.eclipse.che.api.factory.server.FactoryService.VALIDATE_QUERY_PARAMETER; import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION; import static org.eclipse.che.dto.server.DtoFactory.newDto; @@ -30,8 +25,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.lenient; @@ -47,18 +40,12 @@ import com.jayway.restassured.http.ContentType; import com.jayway.restassured.response.Response; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.eclipse.che.api.core.BadRequestException; -import org.eclipse.che.api.core.NotFoundException; -import org.eclipse.che.api.core.Page; -import org.eclipse.che.api.core.model.factory.Factory; import org.eclipse.che.api.core.model.user.User; 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.config.ProjectConfig; import org.eclipse.che.api.core.rest.ApiExceptionMapper; import org.eclipse.che.api.core.rest.shared.dto.ServiceError; @@ -79,16 +66,8 @@ import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl; import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl; import org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl; import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl; -import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl.WorkspaceConfigImplBuilder; -import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl; -import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl.WorkspaceImplBuilder; -import org.eclipse.che.api.workspace.shared.dto.CommandDto; import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto; -import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; -import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto; import org.eclipse.che.commons.env.EnvironmentContext; -import org.eclipse.che.commons.json.JsonHelper; -import org.eclipse.che.commons.lang.Pair; import org.eclipse.che.commons.subject.SubjectImpl; import org.eclipse.che.dto.server.DtoFactory; import org.everrest.assured.EverrestJetty; @@ -155,17 +134,7 @@ public class FactoryServiceTest { lenient() .when(preferenceManager.find(USER_ID)) .thenReturn(ImmutableMap.of("preference", "value")); - service = - new FactoryService( - factoryManager, - userManager, - preferenceManager, - createValidator, - acceptValidator, - editValidator, - factoryBuilderSpy, - workspaceManager, - factoryParametersResolverHolder); + service = new FactoryService(userManager, acceptValidator, factoryParametersResolverHolder); } @Filter @@ -178,348 +147,21 @@ public class FactoryServiceTest { } @Test - public void shouldSaveFactory() throws Exception { - final Factory factory = createFactory(); - final FactoryDto factoryDto = asDto(factory, user); - when(factoryManager.saveFactory(any(FactoryDto.class))).thenReturn(factory); - + public void shouldThrowBadRequestWhenNoURLParameterGiven() throws Exception { + // when + final Map map = new HashMap<>(); final Response response = given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) .contentType(ContentType.JSON) - .body(factoryDto) - .expect() - // .statusCode(200) - .post(SERVICE_PATH); - assertEquals(getFromResponse(response, FactoryDto.class).withLinks(emptyList()), factoryDto); - } - - @Test - public void shouldThrowBadRequestExceptionWhenFactoryConfigurationNotProvided() throws Exception { - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType(ContentType.JSON) - .expect() - .statusCode(400) - .post(SERVICE_PATH); - final String errMessage = getFromResponse(response, ServiceError.class).getMessage(); - assertEquals(errMessage, "Factory configuration required"); - } - - @Test - public void shouldReturnFactoryByIdentifierWithoutValidation() throws Exception { - final Factory factory = createFactory(); - final FactoryDto factoryDto = asDto(factory, user); - when(factoryManager.getById(FACTORY_ID)).thenReturn(factory); - - final Response response = - given() .when() - // .expect() - // .statusCode(200) - .get(SERVICE_PATH + "/" + FACTORY_ID); - - assertEquals(getFromResponse(response, FactoryDto.class).withLinks(emptyList()), factoryDto); - } - - @Test - public void shouldReturnFactoryByIdentifierWithValidation() throws Exception { - final Factory factory = createFactory(); - final FactoryDto factoryDto = asDto(factory, user); - when(factoryManager.getById(FACTORY_ID)).thenReturn(factory); - doNothing().when(acceptValidator).validateOnAccept(any(FactoryDto.class)); - - final Response response = - given() - .when() - .expect() - .statusCode(200) - .get(SERVICE_PATH + "/" + FACTORY_ID + "?validate=true"); - - assertEquals(getFromResponse(response, FactoryDto.class).withLinks(emptyList()), factoryDto); - } - - @Test - public void shouldThrowNotFoundExceptionWhenFactoryIsNotExist() throws Exception { - final String errMessage = format("Factory with id %s is not found", FACTORY_ID); - doThrow(new NotFoundException(errMessage)).when(factoryManager).getById(anyString()); - - final Response response = - given().expect().statusCode(404).when().get(SERVICE_PATH + "/" + FACTORY_ID); - - assertEquals(getFromResponse(response, ServiceError.class).getMessage(), errMessage); - } - - @Test - public void shouldReturnFactoryListByNameAttribute() throws Exception { - final FactoryImpl factory = createFactory(); - doReturn(new Page<>(ImmutableList.of(factory), 0, 1, 1)) - .when(factoryManager) - .getByAttribute(1, 0, ImmutableList.of(Pair.of("name", factory.getName()))); - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType(APPLICATION_JSON) - .when() - .expect() - .statusCode(200) - .get(SERVICE_PATH + "/find?maxItems=1&skipCount=0&name=" + factory.getName()); - - final List res = unwrapDtoList(response, FactoryDto.class); - assertEquals(res.size(), 1); - assertEquals(res.get(0).withLinks(emptyList()), asDto(factory, user)); - } - - @Test - public void shouldFailToReturnFactoryListByWrongAttribute() { - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType(APPLICATION_JSON) - .when() - .expect() - .statusCode(400) - .get(SERVICE_PATH + "/find?maxItems=1&skipCount=0&strange=edrer"); - } - - @Test - public void shouldReturnFactoryListByCreatorAttribute() throws Exception { - final FactoryImpl factory1 = createNamedFactory("factory1"); - final FactoryImpl factory2 = createNamedFactory("factory2"); - doReturn(new Page<>(ImmutableList.of(factory1, factory2), 0, 2, 2)) - .when(factoryManager) - .getByAttribute(2, 0, ImmutableList.of(Pair.of("creator.userId", user.getName()))); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType(APPLICATION_JSON) - .when() - .expect() - .statusCode(200) - .get(SERVICE_PATH + "/find?maxItems=2&skipCount=0&creator.userId=" + user.getName()); - - final Set res = - unwrapDtoList(response, FactoryDto.class) - .stream() - .map(f -> f.withLinks(emptyList())) - .collect(toSet()); - assertEquals(res.size(), 2); - assertTrue(res.containsAll(ImmutableList.of(asDto(factory1, user), asDto(factory2, user)))); - } - - @Test - public void shouldThrowBadRequestWhenGettingFactoryByEmptyAttributeList() throws Exception { - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType(APPLICATION_JSON) - .when() - .expect() - .get(SERVICE_PATH + "/find?maxItems=1&skipCount=0"); + .body(map) + .queryParam(VALIDATE_QUERY_PARAMETER, valueOf(true)) + .post(SERVICE_PATH + "/resolver"); assertEquals(response.getStatusCode(), 400); assertEquals( DTO.createDtoFromJson(response.getBody().asString(), ServiceError.class).getMessage(), - "Query must contain at least one attribute"); - } - - @Test - public void shouldThrowNotFoundExceptionWhenUpdatingNonExistingFactory() throws Exception { - final Factory factory = - createFactoryWithStorage( - FACTORY_NAME, "git", "https://github.com/codenvy/platform-api.git"); - doThrow(new NotFoundException(format("Factory with id %s is not found.", FACTORY_ID))) - .when(factoryManager) - .getById(anyString()); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType(APPLICATION_JSON) - .body(JsonHelper.toJson(factory)) - .when() - .put(SERVICE_PATH + "/" + FACTORY_ID); - - assertEquals(response.getStatusCode(), 404); - assertEquals( - DTO.createDtoFromJson(response.getBody().asString(), ServiceError.class).getMessage(), - format("Factory with id %s is not found.", FACTORY_ID)); - } - - @Test - public void shouldNotBeAbleToUpdateANullFactory() throws Exception { - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType(APPLICATION_JSON) - .when() - .put(SERVICE_PATH + "/" + FACTORY_ID); - - assertEquals(response.getStatusCode(), 400); - assertEquals( - DTO.createDtoFromJson(response.getBody().asString(), ServiceError.class).getMessage(), - "Factory configuration required"); - } - - @Test - public void shouldRemoveFactoryByGivenIdentifier() throws Exception { - final Factory factory = createFactory(); - when(factoryManager.getById(FACTORY_ID)).thenReturn(factory); - - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .param("id", FACTORY_ID) - .expect() - .statusCode(204) - .when() - .delete(SERVICE_PATH + "/" + FACTORY_ID); - - verify(factoryManager).removeFactory(FACTORY_ID); - } - - @Test - public void shouldNotThrowAnyExceptionWhenRemovingNonExistingFactory() throws Exception { - doNothing().when(factoryManager).removeFactory(anyString()); - - Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .param("id", FACTORY_ID) - .when() - .delete(SERVICE_PATH + "/" + FACTORY_ID); - - assertEquals(response.getStatusCode(), 204); - } - - @Test - public void shouldGenerateFactoryJsonIncludeGivenProjects() throws Exception { - // given - final String wsId = "workspace123234"; - WorkspaceImplBuilder ws = WorkspaceImpl.builder(); - WorkspaceConfigImplBuilder wsConfig = WorkspaceConfigImpl.builder(); - ws.setId(wsId); - wsConfig.setProjects( - Arrays.asList( - newDto(ProjectConfigDto.class) - .withPath("/proj1") - .withSource( - newDto(SourceStorageDto.class).withType("git").withLocation("location")), - newDto(ProjectConfigDto.class) - .withPath("/proj2") - .withSource( - newDto(SourceStorageDto.class).withType("git").withLocation("location")))); - wsConfig.setName("wsname"); - wsConfig.setEnvironments(singletonMap("env1", newDto(EnvironmentDto.class))); - wsConfig.setDefaultEnv("env1"); - ws.setStatus(WorkspaceStatus.RUNNING); - wsConfig.setCommands( - singletonList( - newDto(CommandDto.class) - .withName("MCI") - .withType("mvn") - .withCommandLine("clean install"))); - ws.setConfig(wsConfig.build()); - WorkspaceImpl usersWorkspace = ws.build(); - when(workspaceManager.getWorkspace(eq(wsId))).thenReturn(usersWorkspace); - - // when - Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .get("/private" + SERVICE_PATH + "/workspace/" + wsId); - - // then - assertEquals(response.getStatusCode(), 200); - FactoryDto result = DTO.createDtoFromJson(response.getBody().asString(), FactoryDto.class); - assertEquals(result.getWorkspace().getProjects().size(), 2); - } - - @Test - public void shouldNotGenerateFactoryIfNoProjectsWithSourceStorage() throws Exception { - // given - final String wsId = "workspace123234"; - WorkspaceImplBuilder ws = WorkspaceImpl.builder(); - WorkspaceConfigImplBuilder wsConfig = WorkspaceConfigImpl.builder(); - ws.setId(wsId); - wsConfig.setProjects( - Arrays.asList( - newDto(ProjectConfigDto.class).withPath("/proj1"), - newDto(ProjectConfigDto.class).withPath("/proj2"))); - wsConfig.setName("wsname"); - wsConfig.setEnvironments(singletonMap("env1", newDto(EnvironmentDto.class))); - wsConfig.setDefaultEnv("env1"); - ws.setStatus(WorkspaceStatus.RUNNING); - wsConfig.setCommands( - singletonList( - newDto(CommandDto.class) - .withName("MCI") - .withType("mvn") - .withCommandLine("clean install"))); - ws.setConfig(wsConfig.build()); - - WorkspaceImpl usersWorkspace = ws.build(); - when(workspaceManager.getWorkspace(eq(wsId))).thenReturn(usersWorkspace); - - // when - Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .get(SERVICE_PATH + "/workspace/" + wsId); - - // then - assertEquals(response.getStatusCode(), BAD_REQUEST.getStatusCode()); - } - - /** Checks that the user can remove an existing factory */ - @Test - public void shouldBeAbleToRemoveFactory() throws Exception { - final Factory factory = createFactory(); - when(factoryManager.getById(FACTORY_ID)).thenReturn(factory); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .param("id", FACTORY_ID) - .when() - .delete(SERVICE_PATH + "/" + FACTORY_ID); - - assertEquals(response.getStatusCode(), 204); - - // check there was a call on the remove operation with expected ID - verify(factoryManager).removeFactory(FACTORY_ID); - } - - @Test - public void shouldNotThrowExceptionWhenRemoveNoExistingFactory() throws Exception { - doNothing().when(factoryManager).removeFactory(FACTORY_ID); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .param("id", FACTORY_ID) - .when() - .delete(SERVICE_PATH + "/" + FACTORY_ID); - - assertEquals(response.getStatusCode(), 204); + "Cannot build factory with any of the provided parameters. Please check parameters correctness, and resend query."); } @Test @@ -529,17 +171,7 @@ public class FactoryServiceTest { .when(dummyHolder) .getFactoryParametersResolver(anyMap()); // service instance with dummy holder - service = - new FactoryService( - factoryManager, - userManager, - preferenceManager, - createValidator, - acceptValidator, - editValidator, - factoryBuilderSpy, - workspaceManager, - dummyHolder); + service = new FactoryService(userManager, acceptValidator, dummyHolder); // invalid factory final String invalidFactoryMessage = "invalid factory"; @@ -576,24 +208,6 @@ public class FactoryServiceTest { verify(acceptValidator).validateOnAccept(any()); } - @Test - public void shouldThrowBadRequestWhenNoURLParameterGiven() throws Exception { - // when - final Map map = new HashMap<>(); - final Response response = - given() - .contentType(ContentType.JSON) - .when() - .body(map) - .queryParam(VALIDATE_QUERY_PARAMETER, valueOf(true)) - .post(SERVICE_PATH + "/resolver"); - - assertEquals(response.getStatusCode(), 400); - assertEquals( - DTO.createDtoFromJson(response.getBody().asString(), ServiceError.class).getMessage(), - "Cannot build factory with any of the provided parameters. Please check parameters correctness, and resend query."); - } - private FactoryImpl createFactory() { return createNamedFactory(FACTORY_NAME); } diff --git a/wsmaster/che-core-api-workspace/pom.xml b/wsmaster/che-core-api-workspace/pom.xml index d8d2699a7d..424a7bedb1 100644 --- a/wsmaster/che-core-api-workspace/pom.xml +++ b/wsmaster/che-core-api-workspace/pom.xml @@ -86,10 +86,6 @@ org.eclipse.che.core che-core-api-dto - - org.eclipse.che.core - che-core-api-installer-shared - org.eclipse.che.core che-core-api-model diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/WorkspaceService.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/WorkspaceService.java index 246ced152b..4e61269bd6 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/WorkspaceService.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/WorkspaceService.java @@ -12,7 +12,6 @@ package org.eclipse.che.api.workspace.server; import static com.google.common.base.Strings.isNullOrEmpty; -import static java.lang.String.format; import static java.util.Collections.emptyMap; import static java.util.stream.Collectors.toList; import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE; @@ -72,18 +71,13 @@ import org.eclipse.che.api.core.rest.Service; import org.eclipse.che.api.workspace.server.devfile.FileContentProvider; import org.eclipse.che.api.workspace.server.devfile.URLFetcher; import org.eclipse.che.api.workspace.server.devfile.URLFileContentProvider; -import org.eclipse.che.api.workspace.server.model.impl.CommandImpl; -import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl; -import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl; import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl; import org.eclipse.che.api.workspace.server.token.MachineAccessForbidden; import org.eclipse.che.api.workspace.server.token.MachineTokenException; import org.eclipse.che.api.workspace.server.token.MachineTokenProvider; import org.eclipse.che.api.workspace.shared.Constants; -import org.eclipse.che.api.workspace.shared.dto.CommandDto; import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto; import org.eclipse.che.api.workspace.shared.dto.MachineDto; -import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; import org.eclipse.che.api.workspace.shared.dto.RecipeDto; import org.eclipse.che.api.workspace.shared.dto.RuntimeDto; import org.eclipse.che.api.workspace.shared.dto.ServerDto; @@ -141,78 +135,6 @@ public class WorkspaceService extends Service { this.preferredStorageType = preferredStorageType; } - @POST - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Create a new workspace based on the configuration", - notes = - "This operation can be performed only by authorized user," - + "this user will be the owner of the created workspace", - consumes = APPLICATION_JSON, - produces = APPLICATION_JSON, - response = WorkspaceConfigDto.class) - @ApiResponses({ - @ApiResponse(code = 201, message = "The workspace successfully created"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "The user does not have access to create a new workspace"), - @ApiResponse( - code = 409, - message = - "Conflict error occurred during the workspace creation" - + "(e.g. The workspace with such name already exists)"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public Response create( - @ApiParam(value = "The configuration to create the new workspace", required = true) - WorkspaceConfigDto config, - @ApiParam( - value = - "Workspace attribute defined in 'attrName:attrValue' format. " - + "The first ':' is considered as attribute name and value separator", - examples = @Example({@ExampleProperty("attrName:value-with:colon")})) - @QueryParam("attribute") - List attrsList, - @ApiParam( - value = - "The target infrastructure namespace (Kubernetes namespace or OpenShift" - + " project) where the workspace should be deployed to when started. This" - + " parameter is optional. The workspace creation will fail if the Che server" - + " is configured to not allow deploying into that infrastructure namespace.") - @QueryParam("infrastructure-namespace") - String infrastructureNamespace, - @ApiParam( - "If true then the workspace will be immediately " - + "started after it is successfully created") - @QueryParam("start-after-create") - @DefaultValue("false") - Boolean startAfterCreate, - @ApiParam("Namespace where workspace should be created") @QueryParam("namespace") - String namespace) - throws ConflictException, ServerException, BadRequestException, ForbiddenException, - NotFoundException { - requiredNotNull(config, "Workspace configuration"); - final Map attributes = parseAttrs(attrsList); - relativizeRecipeLinks(config); - if (namespace == null) { - namespace = EnvironmentContext.getCurrent().getSubject().getUserName(); - } - if (!isNullOrEmpty(infrastructureNamespace)) { - attributes.put(WORKSPACE_INFRASTRUCTURE_NAMESPACE_ATTRIBUTE, infrastructureNamespace); - } - WorkspaceImpl workspace; - try { - workspace = workspaceManager.createWorkspace(config, namespace, attributes); - } catch (ValidationException x) { - throw new BadRequestException(x.getMessage()); - } - - if (startAfterCreate) { - workspaceManager.startWorkspace(workspace.getId(), null, new HashMap<>()); - } - return Response.status(201).entity(asDtoWithLinksAndToken(workspace)).build(); - } - @Path("/devfile") @POST @Consumes({APPLICATION_JSON, "text/yaml", "text/x-yaml"}) @@ -222,7 +144,7 @@ public class WorkspaceService extends Service { consumes = "application/json, text/yaml, text/x-yaml", produces = APPLICATION_JSON, nickname = "createFromDevfile", - response = WorkspaceConfigDto.class) + response = WorkspaceDto.class) @ApiResponses({ @ApiResponse(code = 201, message = "The workspace successfully created"), @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), @@ -473,55 +395,6 @@ public class WorkspaceService extends Service { return asDtoWithLinksAndToken(workspaceManager.startWorkspace(workspaceId, envName, options)); } - @POST - @Path("/runtime") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Start the temporary workspace from the given configuration", - notes = - "This operation can be performed only by the authorized user or temp user." - + "The workspace starts synchronously") - @ApiResponses({ - @ApiResponse(code = 200, message = "The workspace is starting"), - @ApiResponse(code = 400, message = "The update config is not valid"), - @ApiResponse(code = 404, message = "The workspace with specified id doesn't exist"), - @ApiResponse( - code = 403, - message = "The user is not workspace owner" + "The operation is not allowed for the user"), - @ApiResponse( - code = 409, - message = - "Any conflict occurs during the workspace start" - + "(e.g. workspace with such name already exists"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public WorkspaceDto startFromConfig( - @ApiParam(value = "The configuration to start the workspace from", required = true) - WorkspaceConfigDto config, - @ApiParam("Weather this workspace is temporary or not") - @QueryParam("temporary") - @DefaultValue("false") - Boolean isTemporary, - @ApiParam("Namespace where workspace should be created") @QueryParam("namespace") - String namespace) - throws BadRequestException, ForbiddenException, NotFoundException, ServerException, - ConflictException { - requiredNotNull(config, "Workspace configuration"); - relativizeRecipeLinks(config); - if (namespace == null) { - namespace = EnvironmentContext.getCurrent().getSubject().getUserName(); - } - - try { - WorkspaceImpl workspace = - workspaceManager.startWorkspace(config, namespace, isTemporary, new HashMap<>()); - return asDtoWithLinksAndToken(workspace); - } catch (ValidationException x) { - throw new BadRequestException(x.getMessage()); - } - } - @DELETE @Path("/{id}/runtime") @ApiOperation( @@ -540,293 +413,6 @@ public class WorkspaceService extends Service { workspaceManager.stopWorkspace(id, emptyMap()); } - @POST - @Path("/{id}/command") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Update the workspace by adding a new command to it", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 200, message = "The workspace successfully updated"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "The user does not have access to update the workspace"), - @ApiResponse(code = 404, message = "The workspace not found"), - @ApiResponse(code = 409, message = "The command with such name already exists"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public WorkspaceDto addCommand( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam(value = "The new workspace command", required = true) CommandDto newCommand) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - requiredNotNull(newCommand, "Command"); - WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - workspace.getConfig().getCommands().add(new CommandImpl(newCommand)); - return asDtoWithLinksAndToken(doUpdate(id, workspace)); - } - - @PUT - @Path("/{id}/command/{name}") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Update the workspace command by replacing the command with a new one", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 200, message = "The command successfully updated"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "The user does not have access to update the workspace"), - @ApiResponse(code = 404, message = "The workspace or the command not found"), - @ApiResponse(code = 409, message = "The Command with such name already exists"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public WorkspaceDto updateCommand( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam("The name of the command") @PathParam("name") String cmdName, - @ApiParam(value = "The command update", required = true) CommandDto update) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - requiredNotNull(update, "Command update"); - WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - List commands = workspace.getConfig().getCommands(); - if (!commands.removeIf(cmd -> cmd.getName().equals(cmdName))) { - throw new NotFoundException( - format("Workspace '%s' doesn't contain command '%s'", id, cmdName)); - } - commands.add(new CommandImpl(update)); - return asDtoWithLinksAndToken(doUpdate(id, workspace)); - } - - @DELETE - @Path("/{id}/command/{name}") - @ApiOperation( - value = "Remove the command from the workspace", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 204, message = "The command successfully removed"), - @ApiResponse(code = 403, message = "The user does not have access delete the command"), - @ApiResponse(code = 404, message = "The workspace not found"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public void deleteCommand( - @ApiParam("The id of the workspace") @PathParam("id") String id, - @ApiParam("The name of the command to remove") @PathParam("name") String commandName) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - if (workspace - .getConfig() - .getCommands() - .removeIf(command -> command.getName().equals(commandName))) { - doUpdate(id, workspace); - } - } - - @POST - @Path("/{id}/environment") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Add a new environment to the workspace", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 200, message = "The workspace successfully updated"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "The user does not have access to add the environment"), - @ApiResponse(code = 404, message = "The workspace not found"), - @ApiResponse(code = 409, message = "Environment with such name already exists"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public WorkspaceDto addEnvironment( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam(value = "The new environment", required = true) EnvironmentDto newEnvironment, - @ApiParam(value = "The name of the environment", required = true) @QueryParam("name") - String envName) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - requiredNotNull(newEnvironment, "New environment"); - requiredNotNull(envName, "New environment name"); - relativizeRecipeLinks(newEnvironment); - WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - workspace.getConfig().getEnvironments().put(envName, new EnvironmentImpl(newEnvironment)); - return asDtoWithLinksAndToken(doUpdate(id, workspace)); - } - - @PUT - @Path("/{id}/environment/{name}") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Update the workspace environment by replacing it with a new one", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 200, message = "The environment successfully updated"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "The user does not have access to update the environment"), - @ApiResponse(code = 404, message = "The workspace or the environment not found"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public WorkspaceDto updateEnvironment( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam("The name of the environment") @PathParam("name") String envName, - @ApiParam(value = "The environment update", required = true) EnvironmentDto update) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - requiredNotNull(update, "Environment description"); - relativizeRecipeLinks(update); - final WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - EnvironmentImpl previous = - workspace.getConfig().getEnvironments().put(envName, new EnvironmentImpl(update)); - if (previous == null) { - throw new NotFoundException( - format("Workspace '%s' doesn't contain environment '%s'", id, envName)); - } - return asDtoWithLinksAndToken(doUpdate(id, workspace)); - } - - @DELETE - @Path("/{id}/environment/{name}") - @ApiOperation( - value = "Remove the environment from the workspace", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 204, message = "The environment successfully removed"), - @ApiResponse(code = 403, message = "The user does not have access remove the environment"), - @ApiResponse(code = 404, message = "The workspace not found"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public void deleteEnvironment( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam("The name of the environment") @PathParam("name") String envName) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - final WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - if (workspace.getConfig().getEnvironments().remove(envName) != null) { - doUpdate(id, workspace); - } - } - - @POST - @Path("/{id}/project") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Adds a new project to the workspace", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 200, message = "The project successfully added to the workspace"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "The user does not have access to add the project"), - @ApiResponse(code = 404, message = "The workspace not found"), - @ApiResponse(code = 409, message = "Any conflict error occurs"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public WorkspaceDto addProject( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam(value = "The new project", required = true) ProjectConfigDto newProject) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - requiredNotNull(newProject, "New project config"); - final WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - workspace.getConfig().getProjects().add(new ProjectConfigImpl(newProject)); - return asDtoWithLinksAndToken(doUpdate(id, workspace)); - } - - @PUT - @Path("/{id}/project/{path:.*}") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - @ApiOperation( - value = "Update the workspace project by replacing it with a new one", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 200, message = "The project successfully updated"), - @ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"), - @ApiResponse(code = 403, message = "The user does not have access to update the project"), - @ApiResponse(code = 404, message = "The workspace or the project not found"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public WorkspaceDto updateProject( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam("The path to the project") @PathParam("path") String path, - @ApiParam(value = "The project update", required = true) ProjectConfigDto update) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - requiredNotNull(update, "Project config"); - final WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - final List projects = workspace.getConfig().getProjects(); - final String normalizedPath = path.startsWith("/") ? path : '/' + path; - if (!projects.removeIf(project -> project.getPath().equals(normalizedPath))) { - throw new NotFoundException( - format("Workspace '%s' doesn't contain project with path '%s'", id, normalizedPath)); - } - projects.add(new ProjectConfigImpl(update)); - return asDtoWithLinksAndToken(doUpdate(id, workspace)); - } - - @DELETE - @Path("/{id}/project/{path:.*}") - @ApiOperation( - value = "Remove the project from the workspace", - notes = "This operation can be performed only by the workspace owner") - @ApiResponses({ - @ApiResponse(code = 204, message = "The project successfully removed"), - @ApiResponse(code = 403, message = "The user does not have access remove the project"), - @ApiResponse(code = 404, message = "The workspace not found"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public void deleteProject( - @ApiParam("The workspace id") @PathParam("id") String id, - @ApiParam("The name of the project to remove") @PathParam("path") String path) - throws ServerException, BadRequestException, NotFoundException, ConflictException, - ForbiddenException { - final WorkspaceImpl workspace = workspaceManager.getWorkspace(id); - if (workspace.getConfig() == null) { - throw new ConflictException( - "This method can not be invoked for workspace created from Devfile. Use update workspace method instead."); - } - final String normalizedPath = path.startsWith("/") ? path : '/' + path; - if (workspace - .getConfig() - .getProjects() - .removeIf(project -> project.getPath().equals(normalizedPath))) { - doUpdate(id, workspace); - } - } - @GET @Path("/settings") @Produces(APPLICATION_JSON) diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/environment/InternalEnvironmentFactory.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/environment/InternalEnvironmentFactory.java index 730246420d..fe5941e1c1 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/environment/InternalEnvironmentFactory.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/environment/InternalEnvironmentFactory.java @@ -16,7 +16,6 @@ import static org.eclipse.che.api.workspace.shared.Constants.RECIPE_CONTAINER_SO import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -27,7 +26,6 @@ import org.eclipse.che.api.core.model.workspace.Warning; import org.eclipse.che.api.core.model.workspace.config.Environment; import org.eclipse.che.api.core.model.workspace.config.MachineConfig; import org.eclipse.che.api.core.model.workspace.config.ServerConfig; -import org.eclipse.che.api.installer.shared.model.Installer; import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.commons.annotation.Nullable; @@ -90,9 +88,6 @@ public abstract class InternalEnvironmentFactory for (Map.Entry machineEntry : sourceEnv.getMachines().entrySet()) { MachineConfig machineConfig = machineEntry.getValue(); - - List installers = Collections.emptyList(); - machines.put( machineEntry.getKey(), new InternalMachineConfig( diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java index bd9267d31d..c085c7399a 100644 --- a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java @@ -34,7 +34,6 @@ import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME; import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD; import static org.everrest.assured.JettyHttpServer.SECURE_PATH; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; @@ -61,7 +60,6 @@ import org.eclipse.che.api.core.Page; import org.eclipse.che.api.core.ValidationException; 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.config.ProjectConfig; import org.eclipse.che.api.core.model.workspace.config.ServerConfig; import org.eclipse.che.api.core.model.workspace.devfile.Devfile; import org.eclipse.che.api.core.model.workspace.runtime.Machine; @@ -102,7 +100,6 @@ import org.everrest.assured.EverrestJetty; import org.everrest.core.Filter; import org.everrest.core.GenericContainerRequest; import org.everrest.core.RequestFilter; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.testng.MockitoTestNGListener; import org.testng.annotations.BeforeMethod; @@ -166,40 +163,6 @@ public class WorkspaceServiceTest { preferredStorageType); } - @Test - public void shouldCreateWorkspaceFromConfig() throws Exception { - final WorkspaceConfigDto configDto = createConfigDto(); - final WorkspaceImpl workspace = createWorkspace(configDto); - when(wsManager.createWorkspace(any(WorkspaceConfig.class), anyString(), any())) - .thenReturn(workspace); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(configDto) - .when() - .post( - SECURE_PATH - + "/workspace" - + "?namespace=test" - + "&attribute=factoryId:factory123" - + "&attribute=custom:custom:value"); - - assertEquals(response.getStatusCode(), 201); - assertEquals( - new WorkspaceImpl(unwrapDto(response, WorkspaceDto.class), TEST_ACCOUNT), workspace); - verify(wsManager) - .createWorkspace( - any(WorkspaceConfig.class), - eq("test"), - eq( - ImmutableMap.of( - "factoryId", "factory123", - "custom", "custom:value"))); - } - @Test public void shouldCreateWorkspaceFromDevfile() throws Exception { final DevfileDto devfileDto = createDevfileDto(); @@ -304,71 +267,6 @@ public class WorkspaceServiceTest { assertEquals(error, "boom"); } - @Test - public void shouldUseUsernameAsNamespaceWhenCreatingWorkspaceFromConfigWithoutSpecifiedNamespace() - throws Exception { - final WorkspaceConfigDto configDto = createConfigDto(); - final WorkspaceImpl workspace = createWorkspace(configDto); - when(wsManager.createWorkspace(any(WorkspaceConfig.class), anyString(), any())) - .thenReturn(workspace); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(configDto) - .when() - .post( - SECURE_PATH - + "/workspace" - + "?attribute=factoryId:factory123" - + "&attribute=custom:custom:value"); - - assertEquals(response.getStatusCode(), 201); - assertEquals( - new WorkspaceImpl(unwrapDto(response, WorkspaceDto.class), TEST_ACCOUNT), workspace); - verify(wsManager) - .createWorkspace( - any(WorkspaceConfig.class), - eq(NAMESPACE), - eq( - ImmutableMap.of( - "factoryId", "factory123", - "custom", "custom:value"))); - } - - @Test - public void shouldStartTheWorkspaceAfterItIsCreatedFromConfigWhenStartAfterCreateParamIsTrue() - throws Exception { - final WorkspaceConfigDto configDto = createConfigDto(); - final WorkspaceImpl workspace = createWorkspace(configDto); - when(wsManager.createWorkspace(any(WorkspaceConfig.class), any(), any())).thenReturn(workspace); - - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(configDto) - .when() - .post( - SECURE_PATH - + "/workspace" - + "?attribute=factoryId:factory123" - + "&attribute=custom:custom:value" - + "&start-after-create=true"); - - verify(wsManager).startWorkspace(workspace.getId(), null, emptyMap()); - verify(wsManager) - .createWorkspace( - any(WorkspaceConfig.class), - anyString(), - eq( - ImmutableMap.of( - "factoryId", "factory123", - "custom", "custom:value"))); - } - @Test public void createShouldReturn400WhenAttributesAreNotValid() throws Exception { final Response response = @@ -378,7 +276,7 @@ public class WorkspaceServiceTest { .contentType("application/json") .body(createConfigDto()) .when() - .post(SECURE_PATH + "/workspace?attribute=factoryId=factoryId123"); + .post(SECURE_PATH + "/workspace/devfile?attribute=factoryId=factoryId123"); assertEquals(response.getStatusCode(), 400); assertEquals( @@ -388,43 +286,6 @@ public class WorkspaceServiceTest { + "with colon. For example: attributeName:attributeValue"); } - @Test - public void shouldRelativizeLinksOnCreateWorkspace() throws Exception { - final String initialLocation = "http://localhost:8080/api/recipe/idrecipe123456789/script"; - final WorkspaceConfigDto configDto = createConfigDto(); - configDto - .getEnvironments() - .get(configDto.getDefaultEnv()) - .getRecipe() - .withLocation(initialLocation) - .withType("dockerfile"); - - ArgumentCaptor captor = ArgumentCaptor.forClass(WorkspaceConfigDto.class); - when(wsManager.createWorkspace(captor.capture(), any(), any())) - .thenAnswer(invocation -> createWorkspace(captor.getValue())); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(configDto) - .when() - .post( - SECURE_PATH + "/workspace" + "?namespace=test" + "&attribute=custom:custom:value"); - - assertEquals(response.getStatusCode(), 201); - String savedLocation = - unwrapDto(response, WorkspaceDto.class) - .getConfig() - .getEnvironments() - .get(configDto.getDefaultEnv()) - .getRecipe() - .getLocation(); - - assertEquals(savedLocation, initialLocation.substring(API_ENDPOINT.length())); - } - @Test public void createShouldReturn400WhenConfigIsNotSent() throws Exception { final Response response = @@ -433,10 +294,10 @@ public class WorkspaceServiceTest { .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) .contentType("application/json") .when() - .post(SECURE_PATH + "/workspace"); + .post(SECURE_PATH + "/workspace/devfile"); assertEquals(response.getStatusCode(), 400); - assertEquals(unwrapError(response), "Workspace configuration required"); + assertEquals(unwrapError(response), "Devfile required"); } @Test(dataProvider = "validWorkspaceKeys") @@ -975,47 +836,6 @@ public class WorkspaceServiceTest { "64")); } - @Test - public void shouldStartWorkspaceFromConfig() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.startWorkspace(any(), anyString(), anyBoolean(), any())).thenReturn(workspace); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - final WorkspaceDto workspaceDto = asDto(workspace); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(workspaceDto.getConfig()) - .when() - .post(SECURE_PATH + "/workspace/runtime" + "?namespace=test" + "&temporary=true"); - - assertEquals(response.getStatusCode(), 200); - verify(wsManager).startWorkspace(any(), eq("test"), eq(true), eq(emptyMap())); - } - - @Test - public void shouldUseUsernameAsNamespaceWhenStartingWorkspaceFromConfigWithoutNamespace() - throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.startWorkspace(any(), anyString(), anyBoolean(), any())).thenReturn(workspace); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - final WorkspaceDto workspaceDto = asDto(workspace); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(workspaceDto.getConfig()) - .when() - .post(SECURE_PATH + "/workspace/runtime" + "?temporary=true"); - - assertEquals(response.getStatusCode(), 200); - verify(wsManager).startWorkspace(any(), eq(NAMESPACE), eq(true), eq(emptyMap())); - } - @Test public void shouldStopWorkspace() throws Exception { final WorkspaceImpl workspace = createWorkspace(createConfigDto()); @@ -1032,327 +852,6 @@ public class WorkspaceServiceTest { verify(wsManager).stopWorkspace(workspace.getId(), emptyMap()); } - @Test - public void shouldAddCommand() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - when(wsManager.updateWorkspace(any(), any())).thenReturn(workspace); - final CommandDto commandDto = createCommandDto(); - final int commandsSizeBefore = workspace.getConfig().getCommands().size(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(commandDto) - .when() - .post(SECURE_PATH + "/workspace/" + workspace.getId() + "/command"); - - assertEquals(response.getStatusCode(), 200); - assertEquals( - new WorkspaceImpl(unwrapDto(response, WorkspaceDto.class), TEST_ACCOUNT) - .getConfig() - .getCommands() - .size(), - commandsSizeBefore + 1); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldUpdateCommand() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - when(wsManager.updateWorkspace(any(), any())).thenReturn(workspace); - final CommandDto commandDto = createCommandDto(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(commandDto) - .when() - .put( - SECURE_PATH - + "/workspace/" - + workspace.getId() - + "/command/" - + commandDto.getName()); - - assertEquals(response.getStatusCode(), 200); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldRespond404WhenUpdatingCommandWhichDoesNotExist() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(createCommandDto()) - .when() - .put(SECURE_PATH + "/workspace/" + workspace.getId() + "/command/fake"); - - assertEquals(response.getStatusCode(), 404); - assertEquals( - unwrapError(response), - "Workspace '" + workspace.getId() + "' doesn't contain command 'fake'"); - verify(wsManager, never()).updateWorkspace(any(), any()); - } - - @Test - public void shouldDeleteCommand() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - final int commandsSizeBefore = workspace.getConfig().getCommands().size(); - final CommandImpl firstCommand = workspace.getConfig().getCommands().iterator().next(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .delete( - SECURE_PATH - + "/workspace/" - + workspace.getId() - + "/command/" - + firstCommand.getName()); - - assertEquals(response.getStatusCode(), 204); - assertEquals(workspace.getConfig().getCommands().size(), commandsSizeBefore - 1); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldAddEnvironment() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - when(wsManager.updateWorkspace(any(), any())).thenReturn(workspace); - final EnvironmentDto envDto = createEnvDto(); - final int envsSizeBefore = workspace.getConfig().getEnvironments().size(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(envDto) - .when() - .queryParam("name", "new-env") - .post(SECURE_PATH + "/workspace/" + workspace.getId() + "/environment"); - - assertEquals(response.getStatusCode(), 200); - assertEquals( - new WorkspaceImpl(unwrapDto(response, WorkspaceDto.class), TEST_ACCOUNT) - .getConfig() - .getEnvironments() - .size(), - envsSizeBefore + 1); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldUpdateEnvironment() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - when(wsManager.updateWorkspace(any(), any())).thenReturn(workspace); - final EnvironmentDto envDto = createEnvDto(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(envDto) - .when() - .put( - SECURE_PATH - + "/workspace/" - + workspace.getId() - + "/environment/" - + workspace.getConfig().getDefaultEnv()); - - assertEquals(response.getStatusCode(), 200); - assertEquals(workspace.getConfig().getEnvironments().size(), 1); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldRespond404WhenUpdatingEnvironmentWhichDoesNotExist() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(createEnvDto()) - .when() - .put(SECURE_PATH + "/workspace/" + workspace.getId() + "/environment/fake"); - - assertEquals(response.getStatusCode(), 404); - assertEquals( - unwrapError(response), - "Workspace '" + workspace.getId() + "' doesn't contain environment 'fake'"); - verify(wsManager, never()).updateWorkspace(any(), any()); - } - - @Test - public void shouldDeleteEnvironment() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - Map.Entry envEntry = - workspace.getConfig().getEnvironments().entrySet().iterator().next(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .delete( - SECURE_PATH - + "/workspace/" - + workspace.getId() - + "/environment/" - + envEntry.getKey()); - - assertEquals(response.getStatusCode(), 204); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldRelativizeLinksOnAddEnvironment() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - final String initialLocation = "http://localhost:8080/api/recipe/idrecipe123456789/script"; - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - when(wsManager.updateWorkspace(any(), any())).thenReturn(workspace); - final EnvironmentDto envDto = createEnvDto(); - envDto.getRecipe().withLocation(initialLocation).withType("dockerfile"); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(envDto) - .when() - .queryParam("name", "new-env") - .post(SECURE_PATH + "/workspace/" + workspace.getId() + "/environment"); - - assertEquals(response.getStatusCode(), 200); - String savedLocation = - unwrapDto(response, WorkspaceDto.class) - .getConfig() - .getEnvironments() - .get("new-env") - .getRecipe() - .getLocation(); - - assertEquals(savedLocation, initialLocation.substring(API_ENDPOINT.length())); - } - - @Test - public void shouldAddProject() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - when(wsManager.updateWorkspace(any(), any())).thenReturn(workspace); - final ProjectConfigDto projectDto = createProjectDto(); - final int projectsSizeBefore = workspace.getConfig().getProjects().size(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(projectDto) - .when() - .post(SECURE_PATH + "/workspace/" + workspace.getId() + "/project"); - - assertEquals(response.getStatusCode(), 200); - assertEquals( - new WorkspaceImpl(unwrapDto(response, WorkspaceDto.class), TEST_ACCOUNT) - .getConfig() - .getProjects() - .size(), - projectsSizeBefore + 1); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldUpdateProject() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - when(wsManager.updateWorkspace(any(), any())).thenReturn(workspace); - final ProjectConfigDto projectDto = createProjectDto(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(projectDto) - .when() - .put( - SECURE_PATH - + "/workspace/" - + workspace.getId() - + "/project" - + projectDto.getPath()); - - assertEquals(response.getStatusCode(), 200); - verify(wsManager).updateWorkspace(any(), any()); - } - - @Test - public void shouldRespond404WhenUpdatingProjectWhichDoesNotExist() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .contentType("application/json") - .body(createProjectDto()) - .when() - .put(SECURE_PATH + "/workspace/" + workspace.getId() + "/project/fake"); - - assertEquals(response.getStatusCode(), 404); - assertEquals( - unwrapError(response), - "Workspace '" + workspace.getId() + "' doesn't contain project with path '/fake'"); - verify(wsManager, never()).updateWorkspace(any(), any()); - } - - @Test - public void shouldDeleteProject() throws Exception { - final WorkspaceImpl workspace = createWorkspace(createConfigDto()); - when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); - final ProjectConfig firstProject = workspace.getConfig().getProjects().iterator().next(); - - final Response response = - given() - .auth() - .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD) - .when() - .delete( - SECURE_PATH - + "/workspace/" - + workspace.getId() - + "/project" - + firstProject.getPath()); - - assertEquals(response.getStatusCode(), 204); - verify(wsManager).updateWorkspace(any(), any()); - } - @Test public void shouldBeAbleToGetSettings() { when(wsManager.getSupportedRecipes()).thenReturn(ImmutableSet.of("dockerimage", "dockerfile"));