Removed WorkspaceConfig related REST API (#17682)

* Removed WorkspaceConfig related REST API

Signed-off-by: Sergii Kabashniuk <skabashniuk@redhat.com>
7.20.x
Sergii Kabashniuk 2020-09-01 16:29:12 +03:00 committed by GitHub
parent 7fe641196a
commit e5475206db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 17 additions and 2012 deletions

View File

@ -291,10 +291,6 @@
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-permission-devfile</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-permission-factory</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-permission-logger</artifactId>

View File

@ -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();

View File

@ -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(

View File

@ -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);

View File

@ -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}},
};
}

View File

@ -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;

View File

@ -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},
};
}

View File

@ -28,7 +28,6 @@
<module>che-multiuser-permission-devfile</module>
<module>che-multiuser-permission-workspace</module>
<module>che-multiuser-permission-workspace-activity</module>
<module>che-multiuser-permission-factory</module>
<module>che-multiuser-permission-system</module>
<module>che-multiuser-permission-resource</module>
<module>che-multiuser-permission-logger</module>

View File

@ -1115,11 +1115,6 @@
<artifactId>che-multiuser-permission-devfile</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-permission-factory</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-permission-logger</artifactId>

View File

@ -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<String> skip = ImmutableSet.of("token", "skipCount", "maxItems");
final List<Pair<String, String>> 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<String, String> 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<? extends Factory> factoriesPage =
factoryManager.getByAttribute(maxItems, skipCount, query);
List<FactoryDto> 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<ProjectConfig> 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<ProjectConfigImpl> 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 {

View File

@ -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<String, String> 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<FactoryDto> 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<FactoryDto> 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<String, String> 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);
}

View File

@ -86,10 +86,6 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-installer-shared</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-model</artifactId>

View File

@ -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<String> 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<String, String> 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<CommandImpl> 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<ProjectConfigImpl> 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)

View File

@ -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<T extends InternalEnvironment>
for (Map.Entry<String, ? extends MachineConfig> machineEntry :
sourceEnv.getMachines().entrySet()) {
MachineConfig machineConfig = machineEntry.getValue();
List<Installer> installers = Collections.emptyList();
machines.put(
machineEntry.getKey(),
new InternalMachineConfig(

View File

@ -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<WorkspaceConfigDto> 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<String, EnvironmentImpl> 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"));