REST APIs that allows saving/edit/delete/search/share devfiles (#17843)
* REST APIs that allows saving/edit/delete/search/share devfiles Signed-off-by: Sergii Kabashniuk <skabashniuk@redhat.com>7.20.x
parent
2bd0ea208f
commit
f703f6fe1c
|
|
@ -123,6 +123,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory</artifactId>
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ public class WsMasterModule extends AbstractModule {
|
|||
bind(WorkspaceEntityProvider.class);
|
||||
bind(org.eclipse.che.api.workspace.server.TemporaryWorkspaceRemover.class);
|
||||
bind(org.eclipse.che.api.workspace.server.WorkspaceService.class);
|
||||
bind(org.eclipse.che.api.devfile.server.DevfileService.class);
|
||||
bind(org.eclipse.che.api.devfile.server.UserDevfileEntityProvider.class);
|
||||
install(new FactoryModuleBuilder().build(ServersCheckerFactory.class));
|
||||
|
||||
Multibinder<InternalEnvironmentProvisioner> internalEnvironmentProvisioners =
|
||||
|
|
@ -300,6 +302,7 @@ public class WsMasterModule extends AbstractModule {
|
|||
|
||||
install(new org.eclipse.che.api.user.server.jpa.UserJpaModule());
|
||||
install(new org.eclipse.che.api.workspace.server.jpa.WorkspaceJpaModule());
|
||||
install(new org.eclipse.che.api.devfile.server.jpa.UserDevfileJpaModule());
|
||||
|
||||
bind(org.eclipse.che.api.user.server.CheUserCreator.class);
|
||||
|
||||
|
|
@ -361,6 +364,11 @@ public class WsMasterModule extends AbstractModule {
|
|||
new org.eclipse.che.multiuser.permission.workspace.server.jpa
|
||||
.MultiuserWorkspaceJpaModule());
|
||||
install(new MultiUserWorkspaceActivityModule());
|
||||
install(
|
||||
new org.eclipse.che.multiuser.permission.devfile.server.jpa
|
||||
.MultiuserUserDevfileJpaModule());
|
||||
install(
|
||||
new org.eclipse.che.multiuser.permission.devfile.server.UserDevfileApiPermissionsModule());
|
||||
|
||||
// Permission filters
|
||||
bind(org.eclipse.che.multiuser.permission.system.SystemServicePermissionsFilter.class);
|
||||
|
|
@ -375,7 +383,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.devfile.DevfilePermissionsFilter.class);
|
||||
bind(org.eclipse.che.multiuser.permission.workspace.activity.ActivityPermissionsFilter.class);
|
||||
bind(AdminPermissionInitializer.class).asEagerSingleton();
|
||||
bind(
|
||||
|
|
|
|||
|
|
@ -58,12 +58,14 @@
|
|||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.devfile.SerializableConverter</class>
|
||||
<class>org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.ssh.server.model.impl.SshPairImpl</class>
|
||||
|
||||
<class>org.eclipse.che.multiuser.api.permission.server.model.impl.SystemPermissionsImpl</class>
|
||||
<class>org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions</class>
|
||||
<class>org.eclipse.che.multiuser.permission.workspace.server.model.impl.WorkerImpl</class>
|
||||
<class>org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl</class>
|
||||
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl</class>
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl</class>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.core.model.workspace.devfile;
|
||||
|
||||
/** Devfile that is persisted in permanent storage. */
|
||||
public interface UserDevfile {
|
||||
/** Returns the identifier of this persisted devfile instance. It is mandatory and unique. */
|
||||
String getId();
|
||||
|
||||
/** Returns the name of devfile. It is mandatory. */
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the namespace also known as the account name. This name can be the name of the
|
||||
* organization or the name of the user to which this devfile belong to. Namespace and name
|
||||
* uniquely identify devfile.
|
||||
*/
|
||||
String getNamespace();
|
||||
|
||||
/** Returns description of devfile */
|
||||
String getDescription();
|
||||
|
||||
/** Returns devfile content */
|
||||
Devfile getDevfile();
|
||||
}
|
||||
|
|
@ -83,6 +83,11 @@
|
|||
<artifactId>che-core-api-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory</artifactId>
|
||||
|
|
@ -178,6 +183,11 @@
|
|||
<artifactId>che-multiuser-machine-authentication</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-workspace</artifactId>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjec
|
|||
import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjectsFactory.createUser;
|
||||
import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjectsFactory.createWorker;
|
||||
import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjectsFactory.createWorkspace;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.UPDATE;
|
||||
import static org.eclipse.che.multiuser.resource.spi.jpa.JpaFreeResourcesLimitDao.RemoveFreeResourcesLimitSubscriber;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
|
@ -33,6 +36,7 @@ import static org.testng.Assert.assertNull;
|
|||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
|
@ -54,6 +58,8 @@ import org.eclipse.che.api.core.ConflictException;
|
|||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.factory.server.jpa.FactoryJpaModule;
|
||||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
|
||||
import org.eclipse.che.api.factory.server.spi.FactoryDao;
|
||||
|
|
@ -106,6 +112,10 @@ import org.eclipse.che.multiuser.organization.shared.model.Organization;
|
|||
import org.eclipse.che.multiuser.organization.spi.MemberDao;
|
||||
import org.eclipse.che.multiuser.organization.spi.impl.MemberImpl;
|
||||
import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.jpa.MultiuserUserDevfileJpaModule;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao.RemoveUserDevfilePermissionsBeforeUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.jpa.MultiuserWorkspaceJpaModule;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.WorkerDao;
|
||||
import org.eclipse.che.multiuser.resource.api.AvailableResourcesProvider;
|
||||
|
|
@ -143,6 +153,8 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
private SshDao sshDao;
|
||||
private FactoryDao factoryDao;
|
||||
private WorkerDao workerDao;
|
||||
private UserDevfilePermissionDao userDevfilePermissionDao;
|
||||
private UserDevfileDao userDevfileDao;
|
||||
private SignatureKeyDao signatureKeyDao;
|
||||
private FreeResourcesLimitDao freeResourcesLimitDao;
|
||||
private OrganizationManager organizationManager;
|
||||
|
|
@ -195,6 +207,9 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
|
||||
private FreeResourcesLimitImpl freeResourcesLimit2;
|
||||
|
||||
private UserDevfileImpl devfile;
|
||||
private UserDevfilePermissionImpl devfilePermission;
|
||||
|
||||
private H2JpaCleaner h2JpaCleaner;
|
||||
|
||||
@BeforeMethod
|
||||
|
|
@ -221,6 +236,8 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
install(new MultiuserWorkspaceJpaModule());
|
||||
install(new MachineAuthModule());
|
||||
install(new DevfileModule());
|
||||
install(new MultiuserUserDevfileJpaModule());
|
||||
|
||||
bind(ExecutorServiceWrapper.class).to(NoopExecutorServiceWrapper.class);
|
||||
|
||||
bind(FreeResourcesLimitDao.class).to(JpaFreeResourcesLimitDao.class);
|
||||
|
|
@ -305,6 +322,8 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
workspaceDao = injector.getInstance(WorkspaceDao.class);
|
||||
factoryDao = injector.getInstance(FactoryDao.class);
|
||||
workerDao = injector.getInstance(WorkerDao.class);
|
||||
userDevfileDao = injector.getInstance(UserDevfileDao.class);
|
||||
userDevfilePermissionDao = injector.getInstance(UserDevfilePermissionDao.class);
|
||||
signatureKeyDao = injector.getInstance(SignatureKeyDao.class);
|
||||
freeResourcesLimitDao = injector.getInstance(FreeResourcesLimitDao.class);
|
||||
organizationManager = injector.getInstance(OrganizationManager.class);
|
||||
|
|
@ -334,10 +353,18 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
assertTrue(preferenceDao.getPreferences(user.getId()).isEmpty());
|
||||
assertTrue(sshDao.get(user.getId()).isEmpty());
|
||||
assertTrue(workspaceDao.getByNamespace(account.getName(), 30, 0).isEmpty());
|
||||
assertTrue(userDevfileDao.getByNamespace(account.getName(), 30, 0).isEmpty());
|
||||
assertTrue(factoryDao.getByUser(user.getId(), 30, 0).isEmpty());
|
||||
// Check workers and parent entity is removed
|
||||
assertTrue(workspaceDao.getByNamespace(user2.getId(), 30, 0).isEmpty());
|
||||
assertTrue(userDevfileDao.getByNamespace(user2.getId(), 30, 0).isEmpty());
|
||||
assertEquals(workerDao.getWorkers(workspace3.getId(), 1, 0).getTotalItemsCount(), 0);
|
||||
assertNull(
|
||||
notFoundToNull(
|
||||
() ->
|
||||
userDevfilePermissionDao.getUserDevfilePermission(devfile.getId(), user2.getId())));
|
||||
assertFalse(userDevfileDao.getById(devfile.getId()).isPresent());
|
||||
|
||||
// Permissions are removed
|
||||
// Non-removed user permissions and stack are present
|
||||
// Check existence of organizations
|
||||
|
|
@ -391,6 +418,11 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
assertNotNull(notFoundToNull(() -> organizationManager.getById(childOrganization.getId())));
|
||||
assertNotNull(notFoundToNull(() -> organizationManager.getById(organization2.getId())));
|
||||
assertNotNull(notFoundToNull(() -> signatureKeyDao.get(workspace2.getId())));
|
||||
assertTrue(userDevfileDao.getById(devfile.getId()).isPresent());
|
||||
assertNotNull(
|
||||
notFoundToNull(
|
||||
() ->
|
||||
userDevfilePermissionDao.getUserDevfilePermission(devfile.getId(), user2.getId())));
|
||||
assertFalse(
|
||||
organizationResourcesDistributor.getResourcesCaps(childOrganization.getId()).isEmpty());
|
||||
wipeTestData();
|
||||
|
|
@ -399,7 +431,11 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
@DataProvider(name = "beforeRemoveRollbackActions")
|
||||
public Object[][] beforeRemoveActions() {
|
||||
return new Class[][] {
|
||||
{RemoveOrganizationOnLastUserRemovedEventSubscriber.class, BeforeUserRemovedEvent.class}
|
||||
{RemoveOrganizationOnLastUserRemovedEventSubscriber.class, BeforeUserRemovedEvent.class},
|
||||
{
|
||||
RemoveUserDevfilePermissionsBeforeUserRemovedEventSubscriber.class,
|
||||
BeforeUserRemovedEvent.class
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -453,6 +489,13 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
organizationResourcesDistributor.capResources(
|
||||
childOrganization.getId(),
|
||||
singletonList(new ResourceImpl(RamResourceType.ID, 1024, RamResourceType.UNIT)));
|
||||
|
||||
userDevfileDao.create(
|
||||
devfile = TestObjectsFactory.createUserDevfile("id-dev1", "devfile1", account));
|
||||
userDevfilePermissionDao.store(
|
||||
devfilePermission =
|
||||
new UserDevfilePermissionImpl(
|
||||
devfile.getId(), user2.getId(), ImmutableList.of(READ, DELETE, UPDATE)));
|
||||
}
|
||||
|
||||
private void prepareCreator(String userId) {
|
||||
|
|
@ -477,6 +520,9 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
|
||||
workerDao.removeWorker(workspace3.getId(), user2.getId());
|
||||
|
||||
userDevfilePermissionDao.removeUserDevfilePermission(devfile.getId(), user2.getId());
|
||||
userDevfileDao.remove(devfile.getId());
|
||||
|
||||
factoryDao.remove(factory1.getId());
|
||||
factoryDao.remove(factory2.getId());
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
package org.eclipse.che.multiuser.integration.jpa.cascaderemoval;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.security.KeyPair;
|
||||
|
|
@ -22,6 +24,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl;
|
||||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
|
||||
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
|
||||
|
|
@ -29,6 +32,16 @@ import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
|||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.MetadataImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.SourceImpl;
|
||||
import org.eclipse.che.multiuser.machine.authentication.server.signature.model.impl.SignatureKeyPairImpl;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.model.impl.WorkerImpl;
|
||||
import org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl;
|
||||
|
|
@ -112,5 +125,139 @@ public final class TestObjectsFactory {
|
|||
return new SignatureKeyPairImpl(workspaceId, pair.getPublic(), pair.getPrivate());
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(String id, String name, Account account) {
|
||||
return new UserDevfileImpl(id, account, name, "descr", createDevfile(name));
|
||||
}
|
||||
|
||||
public static DevfileImpl createDevfile(String name) {
|
||||
|
||||
SourceImpl source1 =
|
||||
new SourceImpl(
|
||||
"type1",
|
||||
"http://location",
|
||||
"branch1",
|
||||
"point1",
|
||||
"tag1",
|
||||
"commit1",
|
||||
"sparseCheckoutDir1");
|
||||
ProjectImpl project1 = new ProjectImpl("project1", source1, "path1");
|
||||
|
||||
SourceImpl source2 =
|
||||
new SourceImpl(
|
||||
"type2",
|
||||
"http://location",
|
||||
"branch2",
|
||||
"point2",
|
||||
"tag2",
|
||||
"commit2",
|
||||
"sparseCheckoutDir2");
|
||||
ProjectImpl project2 = new ProjectImpl("project2", source2, "path2");
|
||||
|
||||
ActionImpl action1 =
|
||||
new ActionImpl("exec1", "component1", "run.sh", "/home/user/1", null, null);
|
||||
ActionImpl action2 =
|
||||
new ActionImpl("exec2", "component2", "run.sh", "/home/user/2", null, null);
|
||||
|
||||
CommandImpl command1 =
|
||||
new CommandImpl(name + "-1", singletonList(action1), singletonMap("attr1", "value1"), null);
|
||||
CommandImpl command2 =
|
||||
new CommandImpl(name + "-2", singletonList(action2), singletonMap("attr2", "value2"), null);
|
||||
|
||||
EntrypointImpl entrypoint1 =
|
||||
new EntrypointImpl(
|
||||
"parentName1",
|
||||
singletonMap("parent1", "selector1"),
|
||||
"containerName1",
|
||||
asList("command1", "command2"),
|
||||
asList("arg1", "arg2"));
|
||||
|
||||
EntrypointImpl entrypoint2 =
|
||||
new EntrypointImpl(
|
||||
"parentName2",
|
||||
singletonMap("parent2", "selector2"),
|
||||
"containerName2",
|
||||
asList("command3", "command4"),
|
||||
asList("arg3", "arg4"));
|
||||
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl volume1 =
|
||||
new org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl("name1", "path1");
|
||||
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl volume2 =
|
||||
new org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl("name2", "path2");
|
||||
|
||||
EnvImpl env1 = new EnvImpl("name1", "value1");
|
||||
EnvImpl env2 = new EnvImpl("name2", "value2");
|
||||
|
||||
EndpointImpl endpoint1 = new EndpointImpl("name1", 1111, singletonMap("key1", "value1"));
|
||||
EndpointImpl endpoint2 = new EndpointImpl("name2", 2222, singletonMap("key2", "value2"));
|
||||
|
||||
ComponentImpl component1 =
|
||||
new ComponentImpl(
|
||||
"kubernetes",
|
||||
"component1",
|
||||
"eclipse/che-theia/0.0.1",
|
||||
ImmutableMap.of("java.home", "/home/user/jdk11"),
|
||||
"https://mysite.com/registry/somepath1",
|
||||
"/dev.yaml",
|
||||
"refcontent1",
|
||||
ImmutableMap.of("app.kubernetes.io/component", "db"),
|
||||
asList(entrypoint1, entrypoint2),
|
||||
"image",
|
||||
"256G",
|
||||
"128M",
|
||||
"2",
|
||||
"130m",
|
||||
false,
|
||||
false,
|
||||
singletonList("command"),
|
||||
singletonList("arg"),
|
||||
asList(volume1, volume2),
|
||||
asList(env1, env2),
|
||||
asList(endpoint1, endpoint2));
|
||||
component1.setSelector(singletonMap("key1", "value1"));
|
||||
|
||||
ComponentImpl component2 =
|
||||
new ComponentImpl(
|
||||
"kubernetes",
|
||||
"component2",
|
||||
"eclipse/che-theia/0.0.1",
|
||||
ImmutableMap.of(
|
||||
"java.home",
|
||||
"/home/user/jdk11aertwertert",
|
||||
"java.boolean",
|
||||
true,
|
||||
"java.long",
|
||||
123444L),
|
||||
"https://mysite.com/registry/somepath2",
|
||||
"/dev.yaml",
|
||||
"refcontent2",
|
||||
ImmutableMap.of("app.kubernetes.io/component", "webapp"),
|
||||
asList(entrypoint1, entrypoint2),
|
||||
"image",
|
||||
"256G",
|
||||
"256M",
|
||||
"3",
|
||||
"180m",
|
||||
false,
|
||||
false,
|
||||
singletonList("command"),
|
||||
singletonList("arg"),
|
||||
asList(volume1, volume2),
|
||||
asList(env1, env2),
|
||||
asList(endpoint1, endpoint2));
|
||||
component2.setSelector(singletonMap("key2", "value2"));
|
||||
|
||||
DevfileImpl devfile =
|
||||
new DevfileImpl(
|
||||
"0.0.1",
|
||||
asList(project1, project2),
|
||||
asList(component1, component2),
|
||||
asList(command1, command2),
|
||||
singletonMap("attribute1", "value1"),
|
||||
new MetadataImpl(name));
|
||||
|
||||
return devfile;
|
||||
}
|
||||
|
||||
private TestObjectsFactory() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@
|
|||
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl</class>
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl</class>
|
||||
<class>org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl</class>
|
||||
<class>org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@
|
|||
<artifactId>che-multiuser-api-resource</artifactId>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-workspace</artifactId>
|
||||
|
|
@ -112,6 +117,11 @@
|
|||
<artifactId>che-multiuser-machine-authentication</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-workspace</artifactId>
|
||||
|
|
@ -165,12 +175,6 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>analyze</id>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>unpack-dependencies</goal>
|
||||
|
|
@ -178,9 +182,10 @@
|
|||
<configuration>
|
||||
<outputDirectory>${project.build.testOutputDirectory}</outputDirectory>
|
||||
<includeArtifactIds>che-multiuser-api-resource,
|
||||
che-multiuser-api-organization,
|
||||
che-multiuser-api-permission,
|
||||
che-multiuser-permission-workspace</includeArtifactIds>
|
||||
che-multiuser-api-organization,
|
||||
che-multiuser-api-permission,
|
||||
che-multiuser-permission-devfile,
|
||||
che-multiuser-permission-workspace</includeArtifactIds>
|
||||
<includeScope>test</includeScope>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
|
@ -192,7 +197,7 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<includeArtifactIds>che-core-sql-schema,
|
||||
che-multiuser-sql-schema</includeArtifactIds>
|
||||
che-multiuser-sql-schema</includeArtifactIds>
|
||||
<includes>che-schema/</includes>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
</configuration>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.commons.test.tck.JpaCleaner;
|
||||
|
|
@ -68,6 +69,11 @@ import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
|
|||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaMemberDao;
|
||||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDao;
|
||||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDistributedResourcesDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.UserDevfilePermission;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.model.impl.WorkerImpl;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.WorkerDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaWorkerDao;
|
||||
|
|
@ -159,6 +165,9 @@ public class MultiuserMySqlTckModule extends TckModule {
|
|||
bind(new TypeLiteral<TckRepository<SignatureKeyPairImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(SignatureKeyPairImpl.class));
|
||||
|
||||
bind(new TypeLiteral<TckRepository<UserDevfileImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfileImpl.class));
|
||||
|
||||
// dao
|
||||
bind(OrganizationDao.class).to(JpaOrganizationDao.class);
|
||||
bind(OrganizationDistributedResourcesDao.class)
|
||||
|
|
@ -171,6 +180,12 @@ public class MultiuserMySqlTckModule extends TckModule {
|
|||
bind(new TypeLiteral<PermissionsDao<MemberImpl>>() {}).to(JpaMemberDao.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<MemberImpl>>() {}).to(OrganizationDomain.class);
|
||||
|
||||
bind(UserDevfilePermissionDao.class).to(JpaUserDevfilePermissionDao.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<UserDevfilePermissionImpl>>() {})
|
||||
.to(UserDevfileDomain.class);
|
||||
bind(new TypeLiteral<TckRepository<UserDevfilePermission>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfilePermission.class));
|
||||
|
||||
// SHA-512 ecnryptor is faster than PBKDF2 so it is better for testing
|
||||
bind(PasswordEncryptor.class).to(SHA512PasswordEncryptor.class).in(Singleton.class);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.devfile.SerializableConverter</class>
|
||||
<class>org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl</class>
|
||||
<class>org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.CommandImpl</class>
|
||||
<class>org.eclipse.che.workspace.infrastructure.docker.snapshot.MachineSourceImpl</class>
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@
|
|||
<artifactId>che-multiuser-api-resource</artifactId>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-workspace</artifactId>
|
||||
|
|
@ -107,6 +112,11 @@
|
|||
<artifactId>che-multiuser-machine-authentication</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-workspace</artifactId>
|
||||
|
|
@ -174,6 +184,7 @@
|
|||
<includeArtifactIds>che-multiuser-api-resource,
|
||||
che-multiuser-api-organization,
|
||||
che-multiuser-api-permission,
|
||||
che-multiuser-permission-devfile,
|
||||
che-multiuser-permission-workspace</includeArtifactIds>
|
||||
<includeScope>test</includeScope>
|
||||
</configuration>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.commons.test.tck.JpaCleaner;
|
||||
|
|
@ -68,6 +69,11 @@ import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
|
|||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaMemberDao;
|
||||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDao;
|
||||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDistributedResourcesDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.UserDevfilePermission;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.model.impl.WorkerImpl;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.WorkerDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaWorkerDao;
|
||||
|
|
@ -158,6 +164,9 @@ public class MultiuserPostgresqlTckModule extends TckModule {
|
|||
bind(new TypeLiteral<TckRepository<SignatureKeyPairImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(SignatureKeyPairImpl.class));
|
||||
|
||||
bind(new TypeLiteral<TckRepository<UserDevfileImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfileImpl.class));
|
||||
|
||||
// dao
|
||||
bind(OrganizationDao.class).to(JpaOrganizationDao.class);
|
||||
bind(OrganizationDistributedResourcesDao.class)
|
||||
|
|
@ -170,6 +179,12 @@ public class MultiuserPostgresqlTckModule extends TckModule {
|
|||
bind(new TypeLiteral<PermissionsDao<MemberImpl>>() {}).to(JpaMemberDao.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<MemberImpl>>() {}).to(OrganizationDomain.class);
|
||||
|
||||
bind(UserDevfilePermissionDao.class).to(JpaUserDevfilePermissionDao.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<UserDevfilePermissionImpl>>() {})
|
||||
.to(UserDevfileDomain.class);
|
||||
bind(new TypeLiteral<TckRepository<UserDevfilePermission>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfilePermission.class));
|
||||
|
||||
// SHA-512 ecnryptor is faster than PBKDF2 so it is better for testing
|
||||
bind(PasswordEncryptor.class).to(SHA512PasswordEncryptor.class).in(Singleton.class);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.devfile.SerializableConverter</class>
|
||||
<class>org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl</class>
|
||||
<class>org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.CommandImpl</class>
|
||||
<class>org.eclipse.che.workspace.infrastructure.docker.snapshot.MachineSourceImpl</class>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,18 @@
|
|||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<name>Che Multiuser :: Devfile Permissions</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
|
@ -30,31 +42,94 @@
|
|||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-account</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-user</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-test</artifactId>
|
||||
<artifactId>che-core-commons-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-api-permission</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-api-permission</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-api-permission-shared</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
<artifactId>aopalliance</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.restassured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
|
|
@ -67,7 +142,37 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory-shared</artifactId>
|
||||
<artifactId>che-core-commons-inject</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db-vendor-h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-sql-schema</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-sql-schema</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.jpa</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
@ -75,6 +180,11 @@
|
|||
<artifactId>everrest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
|
|
@ -93,17 +203,20 @@
|
|||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Create the test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<!-- compiler inlines constants, so it is impossible to find reference on dependency -->
|
||||
<execution>
|
||||
<id>analyze</id>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<ignoredDependencies>
|
||||
<ignoreDependency>org.eclipse.che.multiuser:che-multiuser-api-permission</ignoreDependency>
|
||||
</ignoredDependencies>
|
||||
<includes>
|
||||
<include>**/spi/tck/*.*</include>
|
||||
<include>**/TestObjectGenerator.*</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Path;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileService;
|
||||
import org.eclipse.che.everrest.CheMethodInvokerFilter;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.resource.GenericResourceMethod;
|
||||
|
||||
/** Restricts access to methods of {@link DevfileService} by user's permissions. */
|
||||
@Filter
|
||||
@Path("/devfile{path:(/.*)?}")
|
||||
public class DevfilePermissionsFilter extends CheMethodInvokerFilter {
|
||||
|
||||
public static final String GET_SCHEMA_METHOD = "getSchema";
|
||||
|
||||
private final WorkspaceManager workspaceManager;
|
||||
|
||||
@Inject
|
||||
public DevfilePermissionsFilter(WorkspaceManager workspaceManager) {
|
||||
this.workspaceManager = workspaceManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void filter(GenericResourceMethod genericResourceMethod, Object[] arguments)
|
||||
throws ForbiddenException {
|
||||
final String methodName = genericResourceMethod.getMethod().getName();
|
||||
switch (methodName) {
|
||||
// public methods
|
||||
case GET_SCHEMA_METHOD:
|
||||
return;
|
||||
default:
|
||||
throw new ForbiddenException("The user does not have permission to perform this operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import com.google.inject.name.Names;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.model.PermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.filters.UserDevfilePermissionsFilter;
|
||||
|
||||
public class UserDevfileApiPermissionsModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(UserDevfilePermissionsFilter.class);
|
||||
bind(UserDevfileCreatorPermissionsProvider.class).asEagerSingleton();
|
||||
|
||||
Multibinder.newSetBinder(
|
||||
binder(),
|
||||
PermissionsDomain.class,
|
||||
Names.named(SuperPrivilegesChecker.SUPER_PRIVILEGED_DOMAINS))
|
||||
.addBinding()
|
||||
.to(UserDevfileDomain.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.core.notification.EventSubscriber;
|
||||
import org.eclipse.che.api.devfile.shared.event.DevfileCreatedEvent;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Adds permissions for creator after user devfile creation */
|
||||
@Singleton
|
||||
public class UserDevfileCreatorPermissionsProvider implements EventSubscriber<DevfileCreatedEvent> {
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(UserDevfileCreatorPermissionsProvider.class);
|
||||
|
||||
private final UserDevfilePermissionDao userDevfilePermissionDao;
|
||||
private final EventService eventService;
|
||||
|
||||
@Inject
|
||||
public UserDevfileCreatorPermissionsProvider(
|
||||
EventService eventService, UserDevfilePermissionDao userDevfilePermissionDao) {
|
||||
this.userDevfilePermissionDao = userDevfilePermissionDao;
|
||||
this.eventService = eventService;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
void subscribe() {
|
||||
eventService.subscribe(this);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
void unsubscribe() {
|
||||
eventService.unsubscribe(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(DevfileCreatedEvent event) {
|
||||
try {
|
||||
userDevfilePermissionDao.store(
|
||||
new UserDevfilePermissionImpl(
|
||||
event.getUserDevfile().getId(),
|
||||
EnvironmentContext.getCurrent().getSubject().getUserId(),
|
||||
new ArrayList<>(new UserDevfileDomain().getAllowedActions())));
|
||||
} catch (ServerException e) {
|
||||
LOG.error(
|
||||
"Can't add creator's permissions for user devfile with id '"
|
||||
+ event.getUserDevfile().getId()
|
||||
+ "'",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
|
||||
/** Domain for storing devfile's permissions */
|
||||
public class UserDevfileDomain extends AbstractPermissionsDomain<UserDevfilePermissionImpl> {
|
||||
public static final String READ = "read";
|
||||
public static final String DELETE = "delete";
|
||||
public static final String UPDATE = "update";
|
||||
public static final String DOMAIN_ID = "devfile";
|
||||
|
||||
public UserDevfileDomain() {
|
||||
super(DOMAIN_ID, ImmutableList.of(READ, DELETE, UPDATE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDevfilePermissionImpl doCreateInstance(
|
||||
String userId, String instanceId, List<String> allowedActions) {
|
||||
return new UserDevfilePermissionImpl(instanceId, userId, allowedActions);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.filters;
|
||||
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.DOMAIN_ID;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.UPDATE;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Path;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.devfile.server.DevfileService;
|
||||
import org.eclipse.che.api.devfile.server.UserDevfileManager;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.everrest.CheMethodInvokerFilter;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.resource.GenericResourceMethod;
|
||||
|
||||
/**
|
||||
* Restricts access to methods of {@link DevfileService} by users' permissions.
|
||||
*
|
||||
* <p>Filter contains rules for protecting of all methods of {@link DevfileService}.<br>
|
||||
* In case when requested method is unknown filter throws {@link ForbiddenException}
|
||||
*/
|
||||
@Filter
|
||||
@Path("/devfile{path:(/.*)?}")
|
||||
public class UserDevfilePermissionsFilter extends CheMethodInvokerFilter {
|
||||
private final UserDevfileManager userDevfileManager;
|
||||
|
||||
@Inject
|
||||
public UserDevfilePermissionsFilter(UserDevfileManager userDevfileManager) {
|
||||
this.userDevfileManager = userDevfileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(GenericResourceMethod genericResourceMethod, Object[] arguments)
|
||||
throws ForbiddenException {
|
||||
final String methodName = genericResourceMethod.getMethod().getName();
|
||||
switch (methodName) {
|
||||
case "getById":
|
||||
doCheckPermission(DOMAIN_ID, ((String) arguments[0]), READ);
|
||||
break;
|
||||
case "update":
|
||||
doCheckPermission(DOMAIN_ID, ((String) arguments[0]), UPDATE);
|
||||
break;
|
||||
case "delete":
|
||||
doCheckPermission(DOMAIN_ID, ((String) arguments[0]), DELETE);
|
||||
break;
|
||||
case "createFromDevfileYaml":
|
||||
case "createFromUserDevfile":
|
||||
case "getUserDevfiles":
|
||||
case "getSchema":
|
||||
return;
|
||||
default:
|
||||
throw new ForbiddenException("The user does not have permission to perform this operation");
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void doCheckPermission(String domain, String instance, String action) throws ForbiddenException {
|
||||
EnvironmentContext.getCurrent().getSubject().checkPermission(domain, instance, action);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.jpa;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import org.eclipse.che.api.devfile.server.RemoveUserDevfileBeforeAccountRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
|
||||
import org.eclipse.che.multiuser.api.permission.server.spi.PermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao.RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriber;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao.RemoveUserDevfilePermissionsBeforeUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.MultiuserJpaUserDevfileDao;
|
||||
|
||||
public class MultiuserUserDevfileJpaModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(UserDevfilePermissionDao.class).to(JpaUserDevfilePermissionDao.class);
|
||||
bind(UserDevfileDao.class).to(MultiuserJpaUserDevfileDao.class);
|
||||
|
||||
bind(RemoveUserDevfileBeforeAccountRemovedEventSubscriber.class).asEagerSingleton();
|
||||
bind(RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriber.class)
|
||||
.asEagerSingleton();
|
||||
bind(RemoveUserDevfilePermissionsBeforeUserRemovedEventSubscriber.class).asEagerSingleton();
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<UserDevfilePermissionImpl>>() {})
|
||||
.to(UserDevfileDomain.class);
|
||||
|
||||
Multibinder<PermissionsDao<? extends AbstractPermissions>> daos =
|
||||
Multibinder.newSetBinder(
|
||||
binder(), new TypeLiteral<PermissionsDao<? extends AbstractPermissions>>() {});
|
||||
daos.addBinding().to(JpaUserDevfilePermissionDao.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserDevfilePermission {
|
||||
/** Returns user id */
|
||||
String getUserId();
|
||||
|
||||
/** Returns user devfile id */
|
||||
String getUserDevfileId();
|
||||
|
||||
/** Returns list of user devfile actions which can be performed by current user */
|
||||
List<String> getActions();
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.model.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.QueryHint;
|
||||
import javax.persistence.Table;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.UserDevfilePermission;
|
||||
|
||||
/** Data object for {@link UserDevfilePermission} */
|
||||
@Entity(name = "UserDevfilePermission")
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "UserDevfilePermission.getByUserDevfileId",
|
||||
query =
|
||||
"SELECT permission "
|
||||
+ "FROM UserDevfilePermission permission "
|
||||
+ "WHERE permission.userDevfileId = :userDevfileId "),
|
||||
@NamedQuery(
|
||||
name = "UserDevfilePermission.getCountByUserDevfileId",
|
||||
query =
|
||||
"SELECT COUNT(permission) "
|
||||
+ "FROM UserDevfilePermission permission "
|
||||
+ "WHERE permission.userDevfileId = :userDevfileId "),
|
||||
@NamedQuery(
|
||||
name = "UserDevfilePermission.getByUserId",
|
||||
query =
|
||||
"SELECT permission "
|
||||
+ "FROM UserDevfilePermission permission "
|
||||
+ "WHERE permission.userId = :userId "),
|
||||
@NamedQuery(
|
||||
name = "UserDevfilePermission.getByUserAndUserDevfileId",
|
||||
query =
|
||||
"SELECT permission "
|
||||
+ "FROM UserDevfilePermission permission "
|
||||
+ "WHERE permission.userId = :userId "
|
||||
+ "AND permission.userDevfileId = :userDevfileId ",
|
||||
hints = {@QueryHint(name = "eclipselink.query-results-cache", value = "true")})
|
||||
})
|
||||
@Table(name = "che_userdevfile_permissions")
|
||||
public class UserDevfilePermissionImpl extends AbstractPermissions
|
||||
implements UserDevfilePermission {
|
||||
|
||||
@Column(name = "userdevfile_id")
|
||||
private String userDevfileId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "userdevfile_id", insertable = false, updatable = false)
|
||||
private UserDevfileImpl userDevfile;
|
||||
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@Column(name = "actions")
|
||||
@CollectionTable(
|
||||
name = "che_userdevfile_permissions_actions",
|
||||
joinColumns = @JoinColumn(name = "userdevfile_permissions_id"))
|
||||
protected List<String> actions;
|
||||
|
||||
public UserDevfilePermissionImpl() {}
|
||||
|
||||
public UserDevfilePermissionImpl(String userDevfileId, String userId, List<String> actions) {
|
||||
super(userId);
|
||||
this.userDevfileId = userDevfileId;
|
||||
if (actions != null) {
|
||||
this.actions = new ArrayList<>(actions);
|
||||
}
|
||||
}
|
||||
|
||||
public UserDevfilePermissionImpl(UserDevfilePermission userDevfilePermission) {
|
||||
this(
|
||||
userDevfilePermission.getUserDevfileId(),
|
||||
userDevfilePermission.getUserId(),
|
||||
userDevfilePermission.getActions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceId() {
|
||||
return userDevfileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDomainId() {
|
||||
return UserDevfileDomain.DOMAIN_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserDevfileId() {
|
||||
return userDevfileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserDevfilePermissionImpl{"
|
||||
+ "userDevfileId='"
|
||||
+ userDevfileId
|
||||
+ '\''
|
||||
+ ", userDevfile="
|
||||
+ userDevfile
|
||||
+ ", actions="
|
||||
+ actions
|
||||
+ "} "
|
||||
+ super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
UserDevfilePermissionImpl that = (UserDevfilePermissionImpl) o;
|
||||
return Objects.equals(userDevfileId, that.userDevfileId)
|
||||
&& Objects.equals(actions, that.actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), userDevfileId, actions);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
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.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
|
||||
/** Defines data access object contract for {@link UserDevfilePermissionImpl}. */
|
||||
public interface UserDevfilePermissionDao {
|
||||
|
||||
/**
|
||||
* Stores (adds or updates) UserDevfilePermissions.
|
||||
*
|
||||
* @param userDevfilePermissions userDevfilePermissions to store
|
||||
* @return optional with updated userDevfilePermissions, other way empty optional must be returned
|
||||
* @throws NullPointerException when {@code userDevfilePermissions} is null
|
||||
* @throws ServerException when any other error occurs during userDevfilePermissions storing
|
||||
*/
|
||||
Optional<UserDevfilePermissionImpl> store(UserDevfilePermissionImpl userDevfilePermissions)
|
||||
throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets userDevfilePermissions by user and userDevfileId
|
||||
*
|
||||
* @param userDevfileId user devfile identifier
|
||||
* @param userId user identifier
|
||||
* @return userDevfilePermissions instance, never null
|
||||
* @throws NullPointerException when {@code userDevfileId} or {@code userId} is null
|
||||
* @throws NotFoundException when permission with given {@code userDevfileId} and {@code userId}
|
||||
* was not found
|
||||
* @throws ServerException when any other error occurs during permission fetching
|
||||
*/
|
||||
UserDevfilePermissionImpl getUserDevfilePermission(String userDevfileId, String userId)
|
||||
throws ServerException, NotFoundException;
|
||||
|
||||
/**
|
||||
* Removes userDevfilePermissions
|
||||
*
|
||||
* <p>Doesn't throw an exception when userDevfilePermissions with given {@code userDevfileId} and
|
||||
* {@code userId} does not exist
|
||||
*
|
||||
* @param userDevfileId workspace identifier
|
||||
* @param userId user identifier
|
||||
* @throws NullPointerException when {@code userDevfileId} or {@code userId} is null
|
||||
* @throws ServerException when any other error occurs during userDevfilePermissions removing
|
||||
*/
|
||||
void removeUserDevfilePermission(String userDevfileId, String userId) throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets userDevfilePermissions by user devfile id.
|
||||
*
|
||||
* @param userDevfileId user devfile identifier
|
||||
* @param maxItems the maximum number of userDevfilePermissions to return
|
||||
* @param skipCount the number of userDevfilePermissions to skip
|
||||
* @return list of userDevfilePermissions instance
|
||||
* @throws NullPointerException when {@code userDevfileId} is null
|
||||
* @throws ServerException when any other error occurs during userDevfilePermissions fetching
|
||||
*/
|
||||
Page<UserDevfilePermissionImpl> getUserDevfilePermission(
|
||||
String userDevfileId, int maxItems, long skipCount) throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets UserDevfilePermissions by user
|
||||
*
|
||||
* @param userId user identifier
|
||||
* @return list of UserDevfilePermissions instance
|
||||
* @throws NullPointerException when {@code userId} is null
|
||||
* @throws ServerException when any other error occurs during UserDevfilePermissions fetching
|
||||
*/
|
||||
List<UserDevfilePermissionImpl> getUserDevfilePermissionByUser(String userId)
|
||||
throws ServerException;
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi.jpa;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
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.notification.EventService;
|
||||
import org.eclipse.che.api.devfile.server.event.BeforeDevfileRemovedEvent;
|
||||
import org.eclipse.che.api.user.server.event.BeforeUserRemovedEvent;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.core.db.cascade.CascadeEventSubscriber;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.jpa.AbstractJpaPermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
|
||||
/** JPA implementation of {@link UserDevfilePermissionDao}. */
|
||||
public class JpaUserDevfilePermissionDao
|
||||
extends AbstractJpaPermissionsDao<UserDevfilePermissionImpl>
|
||||
implements UserDevfilePermissionDao {
|
||||
|
||||
@Inject
|
||||
public JpaUserDevfilePermissionDao(
|
||||
AbstractPermissionsDomain<UserDevfilePermissionImpl> supportedDomain) {
|
||||
super(supportedDomain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDevfilePermissionImpl get(String userId, String instanceId)
|
||||
throws ServerException, NotFoundException {
|
||||
|
||||
requireNonNull(instanceId, "User devfile identifier required");
|
||||
requireNonNull(userId, "User identifier required");
|
||||
try {
|
||||
return new UserDevfilePermissionImpl(getEntity(wildcardToNull(userId), instanceId));
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserDevfilePermissionImpl> getByUser(String userId) throws ServerException {
|
||||
requireNonNull(userId, "User identifier required");
|
||||
return doGetByUser(wildcardToNull(userId))
|
||||
.stream()
|
||||
.map(UserDevfilePermissionImpl::new)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Page<UserDevfilePermissionImpl> getByInstance(
|
||||
String instanceId, int maxItems, long skipCount) throws ServerException {
|
||||
requireNonNull(instanceId, "User devfile identifier required");
|
||||
checkArgument(
|
||||
skipCount <= Integer.MAX_VALUE,
|
||||
"The number of items to skip can't be greater than " + Integer.MAX_VALUE);
|
||||
|
||||
try {
|
||||
final EntityManager entityManager = managerProvider.get();
|
||||
final List<UserDevfilePermissionImpl> permissions =
|
||||
entityManager
|
||||
.createNamedQuery(
|
||||
"UserDevfilePermission.getByUserDevfileId", UserDevfilePermissionImpl.class)
|
||||
.setParameter("userDevfileId", instanceId)
|
||||
.setMaxResults(maxItems)
|
||||
.setFirstResult((int) skipCount)
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(UserDevfilePermissionImpl::new)
|
||||
.collect(toList());
|
||||
final Long permissionsCount =
|
||||
entityManager
|
||||
.createNamedQuery("UserDevfilePermission.getCountByUserDevfileId", Long.class)
|
||||
.setParameter("userDevfileId", instanceId)
|
||||
.getSingleResult();
|
||||
return new Page<>(permissions, skipCount, maxItems, permissionsCount);
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserDevfilePermissionImpl getEntity(String userId, String instanceId)
|
||||
throws NotFoundException, ServerException {
|
||||
try {
|
||||
return doGet(userId, instanceId);
|
||||
} catch (NoResultException e) {
|
||||
throw new NotFoundException(
|
||||
format("User %s does not have permissions assigned to devfile %s.", instanceId, userId));
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServerException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDevfilePermissionImpl getUserDevfilePermission(String userDevfileId, String userId)
|
||||
throws ServerException, NotFoundException {
|
||||
return new UserDevfilePermissionImpl(get(userId, userDevfileId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserDevfilePermission(String userDevfileId, String userId)
|
||||
throws ServerException {
|
||||
try {
|
||||
super.remove(userId, userDevfileId);
|
||||
} catch (NotFoundException e) {
|
||||
throw new ServerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<UserDevfilePermissionImpl> getUserDevfilePermission(
|
||||
String userDevfileId, int maxItems, long skipCount) throws ServerException {
|
||||
return getByInstance(userDevfileId, maxItems, skipCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserDevfilePermissionImpl> getUserDevfilePermissionByUser(String userId)
|
||||
throws ServerException {
|
||||
return getByUser(userId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected UserDevfilePermissionImpl doGet(String userId, String instanceId) {
|
||||
return managerProvider
|
||||
.get()
|
||||
.createNamedQuery(
|
||||
"UserDevfilePermission.getByUserAndUserDevfileId", UserDevfilePermissionImpl.class)
|
||||
.setParameter("userDevfileId", instanceId)
|
||||
.setParameter("userId", userId)
|
||||
.getSingleResult();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected List<UserDevfilePermissionImpl> doGetByUser(@Nullable String userId)
|
||||
throws ServerException {
|
||||
try {
|
||||
return managerProvider
|
||||
.get()
|
||||
.createNamedQuery("UserDevfilePermission.getByUserId", UserDevfilePermissionImpl.class)
|
||||
.setParameter("userId", userId)
|
||||
.getResultList();
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriber
|
||||
extends CascadeEventSubscriber<BeforeDevfileRemovedEvent> {
|
||||
private static final int PAGE_SIZE = 100;
|
||||
|
||||
@Inject private EventService eventService;
|
||||
@Inject private UserDevfilePermissionDao userDevfilePermissionDao;
|
||||
|
||||
@PostConstruct
|
||||
public void subscribe() {
|
||||
eventService.subscribe(this, BeforeDevfileRemovedEvent.class);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void unsubscribe() {
|
||||
eventService.unsubscribe(this, BeforeDevfileRemovedEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCascadeEvent(BeforeDevfileRemovedEvent event) throws Exception {
|
||||
removeUserDevfilePermissions(event.getUserDevfile().getId(), PAGE_SIZE);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void removeUserDevfilePermissions(String userDevfileId, int pageSize) throws ServerException {
|
||||
Page<UserDevfilePermissionImpl> permissionsPage;
|
||||
do {
|
||||
// skip count always equals to 0 because elements will be shifted after removing previous
|
||||
// items
|
||||
permissionsPage =
|
||||
userDevfilePermissionDao.getUserDevfilePermission(userDevfileId, pageSize, 0);
|
||||
for (UserDevfilePermissionImpl permission : permissionsPage.getItems()) {
|
||||
userDevfilePermissionDao.removeUserDevfilePermission(
|
||||
permission.getInstanceId(), permission.getUserId());
|
||||
}
|
||||
} while (permissionsPage.hasNextPage());
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class RemoveUserDevfilePermissionsBeforeUserRemovedEventSubscriber
|
||||
extends CascadeEventSubscriber<BeforeUserRemovedEvent> {
|
||||
@Inject private EventService eventService;
|
||||
@Inject private UserDevfilePermissionDao userDevfilePermissionDao;
|
||||
|
||||
@PostConstruct
|
||||
public void subscribe() {
|
||||
eventService.subscribe(this, BeforeUserRemovedEvent.class);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void unsubscribe() {
|
||||
eventService.unsubscribe(this, BeforeUserRemovedEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCascadeEvent(BeforeUserRemovedEvent event) throws Exception {
|
||||
for (UserDevfilePermissionImpl permission :
|
||||
userDevfilePermissionDao.getUserDevfilePermissionByUser(event.getUser().getId())) {
|
||||
userDevfilePermissionDao.removeUserDevfilePermission(
|
||||
permission.getInstanceId(), permission.getUserId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi.jpa;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.devfile.server.jpa.JpaUserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
|
||||
/** JPA based implementation of {@link UserDevfileDao}. */
|
||||
@Singleton
|
||||
public class MultiuserJpaUserDevfileDao extends JpaUserDevfileDao {
|
||||
|
||||
@Inject
|
||||
public MultiuserJpaUserDevfileDao(
|
||||
Provider<EntityManager> managerProvider, AccountDao accountDao, EventService eventService) {
|
||||
super(managerProvider, accountDao, eventService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<UserDevfile> getDevfiles(
|
||||
int maxItems,
|
||||
int skipCount,
|
||||
List<Pair<String, String>> filter,
|
||||
List<Pair<String, String>> order)
|
||||
throws ServerException {
|
||||
checkArgument(maxItems > 0, "The number of items has to be positive.");
|
||||
checkArgument(
|
||||
skipCount >= 0,
|
||||
"The number of items to skip can't be negative or greater than " + Integer.MAX_VALUE);
|
||||
|
||||
final Subject subject = EnvironmentContext.getCurrent().getSubject();
|
||||
if (subject.isAnonymous()) {
|
||||
throw new ServerException("Unexpected state. Current user is not set.");
|
||||
}
|
||||
|
||||
return doGetDevfiles(
|
||||
maxItems,
|
||||
skipCount,
|
||||
filter,
|
||||
order,
|
||||
() ->
|
||||
MultiuserUserDevfileSearchQueryBuilder.newBuilder(managerProvider.get())
|
||||
.withUserId(subject.getUserId()));
|
||||
}
|
||||
|
||||
public static class MultiuserUserDevfileSearchQueryBuilder
|
||||
extends JpaUserDevfileDao.UserDevfileSearchQueryBuilder {
|
||||
|
||||
MultiuserUserDevfileSearchQueryBuilder(EntityManager entityManager) {
|
||||
super(entityManager);
|
||||
}
|
||||
|
||||
public MultiuserUserDevfileSearchQueryBuilder withUserId(String userId) {
|
||||
params.put("userId", userId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static MultiuserUserDevfileSearchQueryBuilder newBuilder(EntityManager entityManager) {
|
||||
return new MultiuserUserDevfileSearchQueryBuilder(entityManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaUserDevfileDao.UserDevfileSearchQueryBuilder withFilter(
|
||||
List<Pair<String, String>> filter) {
|
||||
super.withFilter(filter);
|
||||
if (this.filter.isEmpty()) {
|
||||
this.filter = "WHERE permission.userId = :userId AND 'read' MEMBER OF permission.actions";
|
||||
} else {
|
||||
this.filter += " AND permission.userId = :userId AND 'read' MEMBER OF permission.actions";
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedQuery<Long> buildCountQuery() {
|
||||
StringBuilder query =
|
||||
new StringBuilder()
|
||||
.append("SELECT ")
|
||||
.append(" COUNT(userdevfile) ")
|
||||
.append("FROM UserDevfilePermission permission ")
|
||||
.append("LEFT JOIN permission.userDevfile userdevfile ")
|
||||
.append(filter);
|
||||
TypedQuery<Long> typedQuery = entityManager.createQuery(query.toString(), Long.class);
|
||||
params.forEach(typedQuery::setParameter);
|
||||
return typedQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedQuery<UserDevfileImpl> buildSelectItemsQuery() {
|
||||
StringBuilder query =
|
||||
new StringBuilder()
|
||||
.append("SELECT ")
|
||||
.append(" userdevfile ")
|
||||
.append("FROM UserDevfilePermission permission ")
|
||||
.append("LEFT JOIN permission.userDevfile userdevfile ")
|
||||
.append(filter)
|
||||
.append(order);
|
||||
TypedQuery<UserDevfileImpl> typedQuery =
|
||||
entityManager
|
||||
.createQuery(query.toString(), UserDevfileImpl.class)
|
||||
.setFirstResult(skipCount)
|
||||
.setMaxResults(maxItems);
|
||||
params.forEach((k, v) -> typedQuery.setParameter(k, v));
|
||||
return typedQuery;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.devfile.server.DtoConverter;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.MetadataImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.SourceImpl;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
|
||||
public class TestObjectGenerator {
|
||||
|
||||
public static final String TEST_CHE_NAMESPACE = "user";
|
||||
public static final String CURRENT_USER_ID = NameGenerator.generate("usrid", 6);
|
||||
public static final Subject TEST_SUBJECT =
|
||||
new SubjectImpl(TEST_CHE_NAMESPACE, CURRENT_USER_ID, "token", false);
|
||||
public static final String USER_DEVFILE_ID = NameGenerator.generate("usrd", 16);
|
||||
public static final AccountImpl TEST_ACCOUNT =
|
||||
new AccountImpl("acc-id042u3ui3oi", TEST_CHE_NAMESPACE, "test");
|
||||
|
||||
public static UserDevfileDto createUserDevfileDto() {
|
||||
return DtoConverter.asDto(createUserDevfile(NameGenerator.generate("name", 6)));
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile() {
|
||||
return createUserDevfile(NameGenerator.generate("name", 6));
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(String name) {
|
||||
return createUserDevfile(NameGenerator.generate("id", 6), name);
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(String id, String name) {
|
||||
return new UserDevfileImpl(id, TEST_ACCOUNT, name, "devfile description", createDevfile(name));
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(String id, Account account, String name) {
|
||||
return new UserDevfileImpl(id, account, name, "devfile description", createDevfile(name));
|
||||
}
|
||||
|
||||
public static DevfileImpl createDevfile(String name) {
|
||||
return createDevfile(name, "rosetta-");
|
||||
}
|
||||
|
||||
public static DevfileImpl createDevfile(String name, String generatedName) {
|
||||
|
||||
SourceImpl source1 =
|
||||
new SourceImpl(
|
||||
"type1",
|
||||
"http://location",
|
||||
"branch1",
|
||||
"point1",
|
||||
"tag1",
|
||||
"commit1",
|
||||
"sparseCheckoutDir1");
|
||||
ProjectImpl project1 = new ProjectImpl("project1", source1, "path1");
|
||||
|
||||
SourceImpl source2 =
|
||||
new SourceImpl(
|
||||
"type2",
|
||||
"http://location",
|
||||
"branch2",
|
||||
"point2",
|
||||
"tag2",
|
||||
"commit2",
|
||||
"sparseCheckoutDir2");
|
||||
ProjectImpl project2 = new ProjectImpl("project2", source2, "path2");
|
||||
|
||||
ActionImpl action1 =
|
||||
new ActionImpl("exec1", "component1", "run.sh", "/home/user/1", null, null);
|
||||
ActionImpl action2 =
|
||||
new ActionImpl("exec2", "component2", "run.sh", "/home/user/2", null, null);
|
||||
|
||||
CommandImpl command1 =
|
||||
new CommandImpl(name + "-1", singletonList(action1), singletonMap("attr1", "value1"), null);
|
||||
CommandImpl command2 =
|
||||
new CommandImpl(name + "-2", singletonList(action2), singletonMap("attr2", "value2"), null);
|
||||
|
||||
EntrypointImpl entrypoint1 =
|
||||
new EntrypointImpl(
|
||||
"parentName1",
|
||||
singletonMap("parent1", "selector1"),
|
||||
"containerName1",
|
||||
asList("command1", "command2"),
|
||||
asList("arg1", "arg2"));
|
||||
|
||||
EntrypointImpl entrypoint2 =
|
||||
new EntrypointImpl(
|
||||
"parentName2",
|
||||
singletonMap("parent2", "selector2"),
|
||||
"containerName2",
|
||||
asList("command3", "command4"),
|
||||
asList("arg3", "arg4"));
|
||||
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl volume1 =
|
||||
new org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl("name1", "path1");
|
||||
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl volume2 =
|
||||
new org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl("name2", "path2");
|
||||
|
||||
EnvImpl env1 = new EnvImpl("name1", "value1");
|
||||
EnvImpl env2 = new EnvImpl("name2", "value2");
|
||||
|
||||
EndpointImpl endpoint1 = new EndpointImpl("name1", 1111, singletonMap("key1", "value1"));
|
||||
EndpointImpl endpoint2 = new EndpointImpl("name2", 2222, singletonMap("key2", "value2"));
|
||||
|
||||
ComponentImpl component1 =
|
||||
new ComponentImpl(
|
||||
"kubernetes",
|
||||
"component1",
|
||||
"eclipse/che-theia/0.0.1",
|
||||
ImmutableMap.of("java.home", "/home/user/jdk11"),
|
||||
"https://mysite.com/registry/somepath1",
|
||||
"/dev.yaml",
|
||||
"refcontent1",
|
||||
ImmutableMap.of("app.kubernetes.io/component", "db"),
|
||||
asList(entrypoint1, entrypoint2),
|
||||
"image",
|
||||
"256G",
|
||||
"128M",
|
||||
"2",
|
||||
"130m",
|
||||
false,
|
||||
false,
|
||||
singletonList("command"),
|
||||
singletonList("arg"),
|
||||
asList(volume1, volume2),
|
||||
asList(env1, env2),
|
||||
asList(endpoint1, endpoint2));
|
||||
component1.setSelector(singletonMap("key1", "value1"));
|
||||
|
||||
ComponentImpl component2 =
|
||||
new ComponentImpl(
|
||||
"kubernetes",
|
||||
"component2",
|
||||
"eclipse/che-theia/0.0.1",
|
||||
ImmutableMap.of(
|
||||
"java.home",
|
||||
"/home/user/jdk11aertwertert",
|
||||
"java.boolean",
|
||||
true,
|
||||
"java.long",
|
||||
123444L),
|
||||
"https://mysite.com/registry/somepath2",
|
||||
"/dev.yaml",
|
||||
"refcontent2",
|
||||
ImmutableMap.of("app.kubernetes.io/component", "webapp"),
|
||||
asList(entrypoint1, entrypoint2),
|
||||
"image",
|
||||
"256G",
|
||||
"256M",
|
||||
"3",
|
||||
"180m",
|
||||
false,
|
||||
false,
|
||||
singletonList("command"),
|
||||
singletonList("arg"),
|
||||
asList(volume1, volume2),
|
||||
asList(env1, env2),
|
||||
asList(endpoint1, endpoint2));
|
||||
component2.setSelector(singletonMap("key2", "value2"));
|
||||
MetadataImpl metadata = new MetadataImpl(name);
|
||||
metadata.setGenerateName(generatedName);
|
||||
DevfileImpl devfile =
|
||||
new DevfileImpl(
|
||||
"0.0.1",
|
||||
asList(project1, project2),
|
||||
asList(component1, component2),
|
||||
asList(command1, command2),
|
||||
singletonMap("attribute1", "value1"),
|
||||
metadata);
|
||||
|
||||
return devfile;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.filters;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
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.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import com.jayway.restassured.response.Response;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.core.rest.CheJsonProvider;
|
||||
import org.eclipse.che.api.devfile.server.DevfileService;
|
||||
import org.eclipse.che.api.devfile.server.UserDevfileManager;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileEntityProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.TestObjectGenerator;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
import org.everrest.core.RequestFilter;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/** Tests for {@link UserDevfilePermissionsFilter}. */
|
||||
@Listeners(value = {EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class UserDevfilePermissionsFilterTest {
|
||||
private static final String USERNAME = "userok";
|
||||
|
||||
ApiExceptionMapper mapper;
|
||||
|
||||
CheJsonProvider jsonProvider = new CheJsonProvider(new HashSet<>());
|
||||
private DevfileEntityProvider devfileEntityProvider =
|
||||
new DevfileEntityProvider(
|
||||
new DevfileParser(
|
||||
new DevfileSchemaValidator(new DevfileSchemaProvider()),
|
||||
new DevfileIntegrityValidator(Collections.emptyMap())));
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
|
||||
@Mock private static Subject subject;
|
||||
|
||||
@Mock private UserDevfileManager userDevfileManager;
|
||||
|
||||
private UserDevfilePermissionsFilter permissionsFilter;
|
||||
|
||||
@Mock private DevfileService devfileService;
|
||||
private UserDevfileDto userDevfileDto = TestObjectGenerator.createUserDevfileDto();
|
||||
private UserDevfileImpl userDevfile =
|
||||
new UserDevfileImpl(userDevfileDto, TestObjectGenerator.TEST_ACCOUNT);
|
||||
//
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
lenient().when(subject.getUserName()).thenReturn(USERNAME);
|
||||
lenient().when(userDevfileManager.getById(any())).thenReturn(userDevfile);
|
||||
|
||||
permissionsFilter = spy(new UserDevfilePermissionsFilter(userDevfileManager));
|
||||
|
||||
lenient()
|
||||
.doThrow(new ForbiddenException(""))
|
||||
.when(subject)
|
||||
.checkPermission(anyString(), anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCheckAnyPermissionOnDevfileCreate() {
|
||||
// given
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(userDevfileDto)
|
||||
.when()
|
||||
.post(SECURE_PATH + "/devfile/");
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verifyZeroInteractions(subject);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCheckAnyPermissionOnDevfileSearch()
|
||||
throws BadRequestException, ForbiddenException, NotFoundException, ServerException {
|
||||
// given
|
||||
Mockito.when(devfileService.getUserDevfiles(any(), any(), any()))
|
||||
.thenReturn(javax.ws.rs.core.Response.ok().build());
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile/search");
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verifyZeroInteractions(subject);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCheckAnyPermissionOnDevfileSchema()
|
||||
throws BadRequestException, ForbiddenException, NotFoundException, ServerException {
|
||||
// given
|
||||
Mockito.when(devfileService.getSchema()).thenReturn(javax.ws.rs.core.Response.ok().build());
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile");
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verifyZeroInteractions(subject);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckReadPermissionsOnFetchingUserDevfileById() throws Exception {
|
||||
// given
|
||||
Mockito.when(devfileService.getById(eq(userDevfileDto.getId()))).thenReturn(userDevfileDto);
|
||||
doNothing()
|
||||
.when(subject)
|
||||
.checkPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.READ));
|
||||
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile/" + userDevfileDto.getId());
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(devfileService).getById(eq(userDevfileDto.getId()));
|
||||
verify(permissionsFilter)
|
||||
.doCheckPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.READ));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToFailOnCheckPermissionDevfileReadByID() throws ForbiddenException {
|
||||
// given
|
||||
doThrow(new ForbiddenException("forbidden"))
|
||||
.when(subject)
|
||||
.checkPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.READ));
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile/" + userDevfileDto.getId());
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 403);
|
||||
verify(permissionsFilter)
|
||||
.doCheckPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.READ));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldChecksPermissionDevfileUpdate() throws ForbiddenException {
|
||||
// given
|
||||
doNothing()
|
||||
.when(subject)
|
||||
.checkPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.UPDATE));
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(userDevfileDto)
|
||||
.when()
|
||||
.put(SECURE_PATH + "/devfile/" + userDevfileDto.getId());
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(permissionsFilter)
|
||||
.doCheckPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.UPDATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToFailOnCheckPermissionDevfileUpdate() throws ForbiddenException {
|
||||
// given
|
||||
doThrow(new ForbiddenException("forbidden"))
|
||||
.when(subject)
|
||||
.checkPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.UPDATE));
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(userDevfileDto)
|
||||
.when()
|
||||
.put(SECURE_PATH + "/devfile/" + userDevfileDto.getId());
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 403);
|
||||
verify(permissionsFilter)
|
||||
.doCheckPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.UPDATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldChecksPermissionDevfileDelete() throws ForbiddenException {
|
||||
// given
|
||||
doNothing()
|
||||
.when(subject)
|
||||
.checkPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.DELETE));
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/devfile/" + userDevfileDto.getId());
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(permissionsFilter)
|
||||
.doCheckPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.DELETE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToFailOnCheckPermissionDevfileDelete() throws ForbiddenException {
|
||||
// given
|
||||
doThrow(new ForbiddenException("forbidden"))
|
||||
.when(subject)
|
||||
.checkPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.DELETE));
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/devfile/" + userDevfileDto.getId());
|
||||
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 403);
|
||||
verify(permissionsFilter)
|
||||
.doCheckPermission(
|
||||
eq(UserDevfileDomain.DOMAIN_ID),
|
||||
eq(userDevfileDto.getId()),
|
||||
eq(UserDevfileDomain.DELETE));
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.jpa;
|
||||
|
||||
import static org.eclipse.che.commons.lang.NameGenerator.generate;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.TestObjectGenerator.createUserDevfile;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.UPDATE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.MultiuserJpaUserDevfileDao;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class MultiuserJpaUserDevfileDaoTest {
|
||||
private TckResourcesCleaner tckResourcesCleaner;
|
||||
private EntityManager manager;
|
||||
private MultiuserJpaUserDevfileDao dao;
|
||||
|
||||
private List<UserDevfilePermissionImpl> permissions;
|
||||
private List<UserImpl> users;
|
||||
private List<UserDevfileImpl> userDevfiles;
|
||||
private List<AccountImpl> accounts;
|
||||
|
||||
@BeforeClass
|
||||
public void setupEntities() throws Exception {
|
||||
permissions =
|
||||
ImmutableList.of(
|
||||
new UserDevfilePermissionImpl(
|
||||
"devfile_id1", "user1", Arrays.asList(READ, DELETE, UPDATE)),
|
||||
new UserDevfilePermissionImpl("devfile_id2", "user1", Arrays.asList(READ, UPDATE)),
|
||||
new UserDevfilePermissionImpl("devfile_id3", "user1", Arrays.asList(DELETE, UPDATE)),
|
||||
new UserDevfilePermissionImpl(
|
||||
"devfile_id1", "user2", Arrays.asList(READ, DELETE, UPDATE)));
|
||||
|
||||
users =
|
||||
ImmutableList.of(
|
||||
new UserImpl("user1", "user1@com.com", "usr1"),
|
||||
new UserImpl("user2", "user2@com.com", "usr2"));
|
||||
accounts =
|
||||
ImmutableList.of(
|
||||
new AccountImpl("acc-1", NameGenerator.generate("account", 6), "user"),
|
||||
new AccountImpl("acc-2", NameGenerator.generate("account", 6), "user"));
|
||||
userDevfiles =
|
||||
ImmutableList.of(
|
||||
createUserDevfile("devfile_id1", accounts.get(0), generate("name", 6)),
|
||||
createUserDevfile("devfile_id2", accounts.get(0), generate("name", 6)),
|
||||
createUserDevfile("devfile_id3", accounts.get(0), generate("name", 6)));
|
||||
Injector injector = Guice.createInjector(new UserDevfileTckModule());
|
||||
manager = injector.getInstance(EntityManager.class);
|
||||
dao = injector.getInstance(MultiuserJpaUserDevfileDao.class);
|
||||
tckResourcesCleaner = injector.getInstance(TckResourcesCleaner.class);
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
manager.getTransaction().begin();
|
||||
|
||||
users.stream().map(UserImpl::new).forEach(manager::persist);
|
||||
accounts.stream().map(AccountImpl::new).forEach(manager::persist);
|
||||
userDevfiles.stream().map(UserDevfileImpl::new).forEach(manager::persist);
|
||||
permissions.stream().map(UserDevfilePermissionImpl::new).forEach(manager::persist);
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() {
|
||||
manager.getTransaction().begin();
|
||||
|
||||
manager
|
||||
.createQuery("SELECT e FROM UserDevfilePermission e", UserDevfilePermissionImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager
|
||||
.createQuery("SELECT w FROM UserDevfile w", UserDevfileImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager
|
||||
.createQuery("SELECT a FROM Account a", AccountImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
manager
|
||||
.createQuery("SELECT u FROM Usr u", UserImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager.getTransaction().commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetTotalWorkspaceCount() throws ServerException {
|
||||
assertEquals(dao.getTotalCount(), 3);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void shutdown() throws Exception {
|
||||
tckResourcesCleaner.clean();
|
||||
EnvironmentContext.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindDevfilesByByPermissions() throws Exception {
|
||||
EnvironmentContext expected = EnvironmentContext.getCurrent();
|
||||
expected.setSubject(new SubjectImpl("user", users.get(0).getId(), "token", false));
|
||||
List<UserDevfile> results =
|
||||
dao.getDevfiles(30, 0, Collections.emptyList(), Collections.emptyList()).getItems();
|
||||
assertEquals(results.size(), 2);
|
||||
assertTrue(results.contains(userDevfiles.get(0)));
|
||||
assertTrue(results.contains(userDevfiles.get(1)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.jpa;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.account.spi.jpa.JpaAccountDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
|
||||
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.MachineConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
|
||||
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.VolumeImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.SourceImpl;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
import org.eclipse.che.commons.test.db.PersistTestModuleBuilder;
|
||||
import org.eclipse.che.commons.test.tck.TckModule;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.commons.test.tck.repository.JpaTckRepository;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.eclipse.che.core.db.DBInitializer;
|
||||
import org.eclipse.che.core.db.h2.jpa.eclipselink.H2ExceptionHandler;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializer;
|
||||
import org.eclipse.che.core.db.schema.impl.flyway.FlywaySchemaInitializer;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.tck.UserDevfilePermissionDaoTest;
|
||||
import org.h2.Driver;
|
||||
|
||||
public class UserDevfileTckModule extends TckModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
H2DBTestServer server = H2DBTestServer.startDefault();
|
||||
install(
|
||||
new PersistTestModuleBuilder()
|
||||
.setDriver(Driver.class)
|
||||
.runningOn(server)
|
||||
.addEntityClasses(
|
||||
AccountImpl.class,
|
||||
UserImpl.class,
|
||||
WorkspaceImpl.class,
|
||||
WorkspaceConfigImpl.class,
|
||||
ProjectConfigImpl.class,
|
||||
EnvironmentImpl.class,
|
||||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
CommandImpl.class,
|
||||
RecipeImpl.class,
|
||||
VolumeImpl.class,
|
||||
// devfile
|
||||
UserDevfileImpl.class,
|
||||
UserDevfilePermissionImpl.class,
|
||||
ActionImpl.class,
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl.class,
|
||||
ComponentImpl.class,
|
||||
DevfileImpl.class,
|
||||
EndpointImpl.class,
|
||||
EntrypointImpl.class,
|
||||
EnvImpl.class,
|
||||
ProjectImpl.class,
|
||||
SourceImpl.class,
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl.class)
|
||||
.addEntityClass(
|
||||
"org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute")
|
||||
.addClass(SerializableConverter.class)
|
||||
.setExceptionHandler(H2ExceptionHandler.class)
|
||||
.build());
|
||||
bind(DBInitializer.class).asEagerSingleton();
|
||||
bind(SchemaInitializer.class)
|
||||
.toInstance(new FlywaySchemaInitializer(server.getDataSource(), "che-schema"));
|
||||
bind(TckResourcesCleaner.class).toInstance(new H2JpaCleaner(server));
|
||||
|
||||
bind(new TypeLiteral<TckRepository<UserDevfileImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfileImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<UserImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<UserDevfilePermissionImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfilePermissionImpl.class));
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<UserDevfilePermissionImpl>>() {})
|
||||
.to(UserDevfilePermissionDaoTest.TestDomain.class);
|
||||
|
||||
bind(UserDevfilePermissionDao.class).to(JpaUserDevfilePermissionDao.class);
|
||||
bind(AccountDao.class).to(JpaAccountDao.class);
|
||||
bind(new TypeLiteral<TckRepository<AccountImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(AccountImpl.class));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi.jpa;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import javax.persistence.EntityManager;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
public class EntityManagerExceptionInterceptor implements MethodInterceptor {
|
||||
@Inject Provider<EntityManager> emf;
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
||||
emf.get().getTransaction().setRollbackOnly();
|
||||
throw new RuntimeException("Database exception");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi.jpa;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.account.spi.jpa.JpaAccountDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.SourceImpl;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
import org.eclipse.che.commons.test.db.PersistTestModuleBuilder;
|
||||
import org.eclipse.che.commons.test.tck.TckModule;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.commons.test.tck.repository.JpaTckRepository;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.eclipse.che.core.db.DBInitializer;
|
||||
import org.eclipse.che.core.db.h2.jpa.eclipselink.H2ExceptionHandler;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializer;
|
||||
import org.eclipse.che.core.db.schema.impl.flyway.FlywaySchemaInitializer;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.UserDevfilePermission;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.tck.UserDevfilePermissionDaoTest;
|
||||
import org.h2.Driver;
|
||||
|
||||
public class JpaTckModule extends TckModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
H2DBTestServer server = H2DBTestServer.startDefault();
|
||||
install(
|
||||
new PersistTestModuleBuilder()
|
||||
.setDriver(Driver.class)
|
||||
.runningOn(server)
|
||||
.addEntityClasses(
|
||||
AccountImpl.class,
|
||||
UserImpl.class,
|
||||
UserDevfilePermissionImpl.class,
|
||||
// devfile
|
||||
ActionImpl.class,
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl.class,
|
||||
ComponentImpl.class,
|
||||
DevfileImpl.class,
|
||||
EndpointImpl.class,
|
||||
EntrypointImpl.class,
|
||||
EnvImpl.class,
|
||||
ProjectImpl.class,
|
||||
SourceImpl.class,
|
||||
UserDevfileImpl.class,
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl.class)
|
||||
.addClass(SerializableConverter.class)
|
||||
.setExceptionHandler(H2ExceptionHandler.class)
|
||||
.build());
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<UserDevfilePermissionImpl>>() {})
|
||||
.to(UserDevfilePermissionDaoTest.TestDomain.class);
|
||||
|
||||
bind(UserDevfilePermissionDao.class).to(JpaUserDevfilePermissionDao.class);
|
||||
bind(AccountDao.class).to(JpaAccountDao.class);
|
||||
bind(new TypeLiteral<TckRepository<UserDevfilePermission>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfilePermission.class));
|
||||
bind(new TypeLiteral<TckRepository<UserImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<UserDevfileImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfileImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<AccountImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(AccountImpl.class));
|
||||
|
||||
bind(SchemaInitializer.class)
|
||||
.toInstance(new FlywaySchemaInitializer(server.getDataSource(), "che-schema"));
|
||||
bind(DBInitializer.class).asEagerSingleton();
|
||||
bind(TckResourcesCleaner.class).toInstance(new H2JpaCleaner(server));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi.jpa;
|
||||
|
||||
import static org.eclipse.che.commons.lang.NameGenerator.generate;
|
||||
import static org.eclipse.che.inject.Matchers.names;
|
||||
import static org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain.SET_PERMISSIONS;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.matcher.Matchers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.commons.test.tck.TckModule;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.TestObjectGenerator;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class JpaUserDevfilePermissionDaoTest {
|
||||
|
||||
private JpaUserDevfilePermissionDao userDevfilePermissionsDao;
|
||||
private EntityManager manager;
|
||||
private TckResourcesCleaner tckResourcesCleaner;
|
||||
|
||||
@BeforeMethod
|
||||
private void setUpManager() {
|
||||
final Injector injector =
|
||||
Guice.createInjector(new JpaTckModule(), new ExceptionEntityManagerModule());
|
||||
manager = injector.getInstance(EntityManager.class);
|
||||
userDevfilePermissionsDao = injector.getInstance(JpaUserDevfilePermissionDao.class);
|
||||
tckResourcesCleaner = injector.getInstance(TckResourcesCleaner.class);
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
private void cleanup() {
|
||||
manager.getTransaction().begin();
|
||||
final List<Object> entities = new ArrayList<>();
|
||||
entities.addAll(manager.createQuery("SELECT p FROM UserDevfilePermission p").getResultList());
|
||||
entities.addAll(manager.createQuery("SELECT d FROM UserDevfile d").getResultList());
|
||||
entities.addAll(manager.createQuery("SELECT a FROM Account a").getResultList());
|
||||
entities.addAll(manager.createQuery("SELECT u FROM Usr u").getResultList());
|
||||
for (Object entity : entities) {
|
||||
manager.remove(entity);
|
||||
}
|
||||
manager.getTransaction().commit();
|
||||
tckResourcesCleaner.clean();
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = ServerException.class,
|
||||
expectedExceptionsMessageRegExp = "Database exception")
|
||||
public void shouldThrowServerExceptionOnExistsWhenRuntimeExceptionOccursInDoGetMethod()
|
||||
throws Exception {
|
||||
|
||||
// Persist the account
|
||||
manager.getTransaction().begin();
|
||||
manager.persist(TestObjectGenerator.TEST_ACCOUNT);
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
|
||||
final UserDevfileImpl userDevfile = TestObjectGenerator.createUserDevfile();
|
||||
// Persist the userdevfile
|
||||
manager.getTransaction().begin();
|
||||
manager.persist(userDevfile);
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
|
||||
final UserImpl user = new UserImpl(generate("user", 6), "user0@com.com", "usr0");
|
||||
// Persist the user
|
||||
manager.getTransaction().begin();
|
||||
manager.persist(user);
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
|
||||
// Persist the worker
|
||||
UserDevfilePermissionImpl worker =
|
||||
new UserDevfilePermissionImpl(
|
||||
userDevfile.getId(), user.getId(), Collections.singletonList(SET_PERMISSIONS));
|
||||
manager.getTransaction().begin();
|
||||
manager.persist(worker);
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
|
||||
userDevfilePermissionsDao.exists(user.getId(), userDevfile.getId(), SET_PERMISSIONS);
|
||||
}
|
||||
|
||||
public class ExceptionEntityManagerModule extends TckModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
MethodInterceptor interceptor = new EntityManagerExceptionInterceptor();
|
||||
requestInjection(interceptor);
|
||||
bindInterceptor(
|
||||
Matchers.subclassesOf(JpaUserDevfilePermissionDao.class), names("doGet"), interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi.jpa;
|
||||
|
||||
import static org.eclipse.che.commons.lang.NameGenerator.generate;
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
import javax.persistence.EntityManager;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.devfile.server.jpa.JpaUserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.TestObjectGenerator;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaUserDevfilePermissionDao.RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriber;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/** Tests for {@link RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriber} */
|
||||
public class RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriberTest {
|
||||
private TckResourcesCleaner tckResourcesCleaner;
|
||||
private EntityManager manager;
|
||||
private JpaUserDevfilePermissionDao userDevfilePermissionsDao;
|
||||
private JpaUserDevfileDao userDevfileDao;
|
||||
|
||||
private RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriber subscriber;
|
||||
|
||||
private UserDevfileImpl userDevfile;
|
||||
private UserDevfilePermissionImpl[] userDevfilePermissions;
|
||||
private UserImpl[] users;
|
||||
|
||||
@BeforeClass
|
||||
public void setupEntities() throws Exception {
|
||||
|
||||
users =
|
||||
new UserImpl[] {
|
||||
new UserImpl("user1", "user1@com.com", "usr1"),
|
||||
new UserImpl("user2", "user2@com.com", "usr2")
|
||||
};
|
||||
|
||||
userDevfile = TestObjectGenerator.createUserDevfile("devfile_id1", generate("name", 6));
|
||||
|
||||
userDevfilePermissions =
|
||||
new UserDevfilePermissionImpl[] {
|
||||
new UserDevfilePermissionImpl(
|
||||
userDevfile.getId(), "user1", Arrays.asList("read", "use", "run")),
|
||||
new UserDevfilePermissionImpl(userDevfile.getId(), "user2", Arrays.asList("read", "use"))
|
||||
};
|
||||
|
||||
Injector injector = Guice.createInjector(new JpaTckModule());
|
||||
|
||||
manager = injector.getInstance(EntityManager.class);
|
||||
userDevfilePermissionsDao = injector.getInstance(JpaUserDevfilePermissionDao.class);
|
||||
userDevfileDao = injector.getInstance(JpaUserDevfileDao.class);
|
||||
subscriber =
|
||||
injector.getInstance(
|
||||
RemoveUserDevfilePermissionsBeforeUserDevfileRemovedEventSubscriber.class);
|
||||
subscriber.subscribe();
|
||||
tckResourcesCleaner = injector.getInstance(TckResourcesCleaner.class);
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
manager.getTransaction().begin();
|
||||
manager.persist(userDevfile);
|
||||
Stream.of(users).forEach(manager::persist);
|
||||
manager.persist(TestObjectGenerator.TEST_ACCOUNT);
|
||||
Stream.of(userDevfilePermissions).forEach(manager::persist);
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() {
|
||||
manager.getTransaction().begin();
|
||||
|
||||
manager
|
||||
.createQuery("SELECT e FROM UserDevfilePermission e", UserDevfilePermissionImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager
|
||||
.createQuery("SELECT w FROM UserDevfile w", UserDevfileImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager
|
||||
.createQuery("SELECT a FROM Account a", AccountImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
manager
|
||||
.createQuery("SELECT u FROM Usr u", UserImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager.getTransaction().commit();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void shutdown() throws Exception {
|
||||
subscriber.unsubscribe();
|
||||
tckResourcesCleaner.clean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveAllPermissionsWhenUserDevfileIsRemoved() throws Exception {
|
||||
userDevfileDao.remove(userDevfile.getId());
|
||||
|
||||
assertEquals(
|
||||
userDevfilePermissionsDao
|
||||
.getUserDevfilePermission(userDevfile.getId(), 1, 0)
|
||||
.getTotalItemsCount(),
|
||||
0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveAllPermissionsWhenPageSizeEqualsToOne() throws Exception {
|
||||
subscriber.removeUserDevfilePermissions(userDevfile.getId(), 1);
|
||||
|
||||
assertEquals(
|
||||
userDevfilePermissionsDao
|
||||
.getUserDevfilePermission(userDevfile.getId(), 1, 0)
|
||||
.getTotalItemsCount(),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.spi.tck;
|
||||
|
||||
import static org.eclipse.che.commons.lang.NameGenerator.generate;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.TestObjectGenerator.createUserDevfile;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.UPDATE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
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.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.commons.test.tck.TckListener;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepositoryException;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.TestObjectGenerator;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.UserDevfilePermission;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.model.impl.UserDevfilePermissionImpl;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.spi.UserDevfilePermissionDao;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/** Compatibility test for {@link UserDevfilePermissionDao} */
|
||||
@Listeners(TckListener.class)
|
||||
@Test(suiteName = "UserDevfilePermissionTck")
|
||||
public class UserDevfilePermissionDaoTest {
|
||||
|
||||
@Inject private UserDevfilePermissionDao permissionDao;
|
||||
|
||||
@Inject private TckRepository<UserDevfilePermission> permissionTckRepository;
|
||||
|
||||
@Inject private TckRepository<UserImpl> userRepository;
|
||||
|
||||
@Inject private TckRepository<UserDevfileImpl> devfileRepository;
|
||||
|
||||
@Inject private TckRepository<AccountImpl> accountRepository;
|
||||
|
||||
UserDevfilePermissionImpl[] permissions;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws TckRepositoryException {
|
||||
accountRepository.createAll(ImmutableList.of(TestObjectGenerator.TEST_ACCOUNT));
|
||||
permissions =
|
||||
new UserDevfilePermissionImpl[] {
|
||||
new UserDevfilePermissionImpl(
|
||||
"devfile_id1", "user1", Arrays.asList(READ, DELETE, UPDATE)),
|
||||
new UserDevfilePermissionImpl("devfile_id1", "user2", Arrays.asList(READ, DELETE)),
|
||||
new UserDevfilePermissionImpl("devfile_id2", "user1", Arrays.asList(READ, UPDATE)),
|
||||
new UserDevfilePermissionImpl(
|
||||
"devfile_id2", "user2", Arrays.asList(READ, DELETE, UPDATE)),
|
||||
new UserDevfilePermissionImpl("devfile_id2", "user0", Arrays.asList(READ, DELETE, UPDATE))
|
||||
};
|
||||
|
||||
final UserImpl[] users =
|
||||
new UserImpl[] {
|
||||
new UserImpl("user0", "user0@com.com", "usr0"),
|
||||
new UserImpl("user1", "user1@com.com", "usr1"),
|
||||
new UserImpl("user2", "user2@com.com", "usr2")
|
||||
};
|
||||
userRepository.createAll(Arrays.asList(users));
|
||||
|
||||
devfileRepository.createAll(
|
||||
ImmutableList.of(
|
||||
createUserDevfile("devfile_id1", generate("name", 6)),
|
||||
createUserDevfile("devfile_id2", generate("name", 6)),
|
||||
createUserDevfile("devfile_id3", generate("name", 6)),
|
||||
createUserDevfile("devfile_id4", generate("name", 6)),
|
||||
createUserDevfile("devfile_id5", generate("name", 6))));
|
||||
|
||||
permissionTckRepository.createAll(
|
||||
Stream.of(permissions).map(UserDevfilePermissionImpl::new).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanUp() throws TckRepositoryException {
|
||||
permissionTckRepository.removeAll();
|
||||
devfileRepository.removeAll();
|
||||
accountRepository.removeAll();
|
||||
userRepository.removeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldStorePermissions() throws Exception {
|
||||
UserDevfilePermissionImpl permission =
|
||||
new UserDevfilePermissionImpl("devfile_id1", "user0", Arrays.asList(READ, DELETE, UPDATE));
|
||||
permissionDao.store(permission);
|
||||
Assert.assertEquals(
|
||||
permissionDao.getUserDevfilePermission("devfile_id1", "user0"),
|
||||
new UserDevfilePermissionImpl(permission));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReplaceExistingPermissionOnStoring() throws Exception {
|
||||
UserDevfilePermissionImpl replace =
|
||||
new UserDevfilePermissionImpl("devfile_id1", "user1", Collections.singletonList("READ"));
|
||||
permissionDao.store(replace);
|
||||
Assert.assertEquals(permissionDao.getUserDevfilePermission("devfile_id1", "user1"), replace);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenStoringArgumentIsNull() throws Exception {
|
||||
permissionDao.store(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPermissionByWorkspaceIdAndUserId() throws Exception {
|
||||
Assert.assertEquals(
|
||||
permissionDao.getUserDevfilePermission("devfile_id1", "user1"), permissions[0]);
|
||||
Assert.assertEquals(
|
||||
permissionDao.getUserDevfilePermission("devfile_id2", "user2"), permissions[3]);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenGetPermissionDevfileIdArgumentIsNull() throws Exception {
|
||||
permissionDao.getUserDevfilePermission(null, "user1");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenGetPermissionUserIdArgumentIsNull() throws Exception {
|
||||
permissionDao.getUserDevfilePermission("devfile_id1", null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class)
|
||||
public void shouldThrowNotFoundExceptionOnGetIfPermissionWithSuchDevfileIdOrUserIdDoesNotExist()
|
||||
throws Exception {
|
||||
permissionDao.getUserDevfilePermission("devfile_id9", "user1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPermissionsByDevfileId() throws Exception {
|
||||
Page<UserDevfilePermissionImpl> permissionsPage =
|
||||
permissionDao.getUserDevfilePermission("devfile_id2", 1, 1);
|
||||
|
||||
final List<UserDevfilePermissionImpl> fetchedPermissions = permissionsPage.getItems();
|
||||
assertEquals(permissionsPage.getTotalItemsCount(), 3);
|
||||
assertEquals(permissionsPage.getItemsCount(), 1);
|
||||
assertTrue(
|
||||
fetchedPermissions.contains(permissions[2])
|
||||
^ fetchedPermissions.contains(permissions[3])
|
||||
^ fetchedPermissions.contains(permissions[4]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPermissionsByUserId() throws Exception {
|
||||
List<UserDevfilePermissionImpl> actual = permissionDao.getUserDevfilePermissionByUser("user1");
|
||||
List<UserDevfilePermissionImpl> expected = Arrays.asList(permissions[0], permissions[2]);
|
||||
assertEquals(actual.size(), expected.size());
|
||||
assertTrue(new HashSet<>(actual).equals(new HashSet<>(expected)));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenGetPermissionsByDevfileArgumentIsNull() throws Exception {
|
||||
permissionDao.getUserDevfilePermission(null, 1, 0);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenGetPermissionsByUserArgumentIsNull() throws Exception {
|
||||
permissionDao.getUserDevfilePermissionByUser(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnEmptyListIfPermissionsWithSuchDevfileIdDoesNotFound() throws Exception {
|
||||
assertEquals(
|
||||
0, permissionDao.getUserDevfilePermission("unexisted_devfile_id", 1, 0).getItemsCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnEmptyListIfPermissionsWithSuchUserIdDoesNotFound() throws Exception {
|
||||
assertEquals(0, permissionDao.getUserDevfilePermissionByUser("unexisted_user").size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemovePermission() throws Exception {
|
||||
permissionDao.removeUserDevfilePermission("devfile_id1", "user1");
|
||||
assertEquals(1, permissionDao.getUserDevfilePermissionByUser("user1").size());
|
||||
assertNull(
|
||||
notFoundToNull(() -> permissionDao.getUserDevfilePermission("devfile_id1", "user1")));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenRemovePermissionDevfileIdArgumentIsNull() throws Exception {
|
||||
permissionDao.removeUserDevfilePermission(null, "user1");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenRemovePermissionUserIdArgumentIsNull() throws Exception {
|
||||
permissionDao.removeUserDevfilePermission("devfile_id1", null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ServerException.class)
|
||||
public void shouldThrowNotFoundExceptionOnRemoveIfPermissionWithSuchDevfileIdDoesNotExist()
|
||||
throws Exception {
|
||||
permissionDao.removeUserDevfilePermission("unexisted_ws", "user1");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ServerException.class)
|
||||
public void shouldThrowNotFoundExceptionOnRemoveIfPermissionWithSuchUserIdDoesNotExist()
|
||||
throws Exception {
|
||||
permissionDao.removeUserDevfilePermission("devfile_id1", "unexisted_user");
|
||||
}
|
||||
|
||||
public static class TestDomain extends AbstractPermissionsDomain<UserDevfilePermissionImpl> {
|
||||
public TestDomain() {
|
||||
super(UserDevfileDomain.DOMAIN_ID, Arrays.asList(READ, DELETE, UPDATE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserDevfilePermissionImpl doCreateInstance(
|
||||
String userId, String instanceId, List<String> allowedActions) {
|
||||
return new UserDevfilePermissionImpl(userId, instanceId, allowedActions);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T notFoundToNull(Callable<T> action) throws Exception {
|
||||
try {
|
||||
return action.call();
|
||||
} catch (NotFoundException x) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permissions.devfile;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
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.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.jayway.restassured.response.Response;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileService;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.multiuser.permission.devfile.DevfilePermissionsFilter;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
import org.everrest.core.RequestFilter;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(value = {EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class DevfilePermissionsFilterTest {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
|
||||
@Mock private static Subject subject;
|
||||
|
||||
@Mock private DevfileService service;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@InjectMocks
|
||||
private DevfilePermissionsFilter permissionsFilter;
|
||||
|
||||
@Test
|
||||
public void shouldTestThatAllPublicMethodsAreCoveredByPermissionsFilter() throws Exception {
|
||||
// given
|
||||
final List<String> collect =
|
||||
Stream.of(DevfileService.class.getDeclaredMethods())
|
||||
.filter(method -> Modifier.isPublic(method.getModifiers()))
|
||||
.map(Method::getName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// then
|
||||
assertEquals(collect.size(), 1);
|
||||
assertTrue(collect.contains(DevfilePermissionsFilter.GET_SCHEMA_METHOD));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCheckPermissionsOnExportingSchema() throws Exception {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.che.multiuser.permission.devfile.server.spi.jpa.JpaTckModule
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-multiuser-permission</artifactId>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<version>7.19.0-SNAPSHOT</version>
|
||||
<version>7.20.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-multiuser-permission-factory</artifactId>
|
||||
<name>Che Multiuser :: Factory Permissions</name>
|
||||
|
|
|
|||
|
|
@ -11,36 +11,15 @@
|
|||
*/
|
||||
package org.eclipse.che.multiuser.permission.factory;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.WorkspaceDomain.DOMAIN_ID;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.WorkspaceDomain.READ;
|
||||
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.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import com.jayway.restassured.response.Response;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.factory.server.FactoryManager;
|
||||
import org.eclipse.che.api.factory.server.FactoryService;
|
||||
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
|
|
@ -85,7 +64,6 @@ public class FactoryPermissionsFilterTest {
|
|||
@DataProvider(name = "publicMethods")
|
||||
public Object[][] publicMethods() {
|
||||
return new Object[][] {
|
||||
|
||||
{"resolveFactory", new Class[] {Map.class, Boolean.class}},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
--
|
||||
-- Copyright (c) 2012-2020 Red Hat, Inc.
|
||||
-- This program and the accompanying materials are made
|
||||
-- available under the terms of the Eclipse Public License 2.0
|
||||
-- which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
--
|
||||
-- SPDX-License-Identifier: EPL-2.0
|
||||
--
|
||||
-- Contributors:
|
||||
-- Red Hat, Inc. - initial API and implementation
|
||||
--
|
||||
|
||||
-- User devfile permissions -----------------------------------------------------------
|
||||
CREATE TABLE che_userdevfile_permissions (
|
||||
id VARCHAR(255) NOT NULL,
|
||||
user_id VARCHAR(255),
|
||||
userdevfile_id VARCHAR(255),
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
-- indexes
|
||||
CREATE UNIQUE INDEX che_index_userdevfile_permissions_user_id_userdevfile_id ON che_userdevfile_permissions (user_id, userdevfile_id);
|
||||
CREATE INDEX che_index_userdevfile_permissions_userdevfile_id ON che_userdevfile_permissions (userdevfile_id);
|
||||
-- constraints
|
||||
ALTER TABLE che_userdevfile_permissions ADD CONSTRAINT che_fk_userdevfile_permissions_user_id FOREIGN KEY (user_id) REFERENCES usr (id);
|
||||
ALTER TABLE che_userdevfile_permissions ADD CONSTRAINT che_fk_userdevfile_permissions_workspace_id FOREIGN KEY (userdevfile_id) REFERENCES userdevfile (id);
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
-- User devfile permission actions --------------------------------------------------------------
|
||||
CREATE TABLE che_userdevfile_permissions_actions (
|
||||
userdevfile_permissions_id VARCHAR(255),
|
||||
actions VARCHAR(255)
|
||||
);
|
||||
-- indexes
|
||||
CREATE INDEX che_index_userdevfile_permissions_actions_actions ON che_userdevfile_permissions_actions (actions);
|
||||
CREATE INDEX che_index_userdevfile_permissions_actions_userdevfile_id ON che_userdevfile_permissions_actions (userdevfile_permissions_id);
|
||||
-- constraints
|
||||
ALTER TABLE che_userdevfile_permissions_actions ADD CONSTRAINT che_fk_userdevfile_permissions_actions_id FOREIGN KEY (userdevfile_permissions_id) REFERENCES che_userdevfile_permissions(id);
|
||||
--------------------------------------------------------------------------------
|
||||
22
pom.xml
22
pom.xml
|
|
@ -701,6 +701,22 @@
|
|||
<artifactId>che-core-api-core</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<version>${che.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile-shared</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
|
|
@ -1118,6 +1134,12 @@
|
|||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-devfile</artifactId>
|
||||
<version>${che.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-permission-logger</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>che-master-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.20.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-devfile-shared</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Che Core :: API :: Devfile :: Shared</name>
|
||||
<properties>
|
||||
<dto-generator-out-directory>${project.build.directory}/generated-sources/dto/</dto-generator-out-directory>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace-shared</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto-maven-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile-shared</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace-shared</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<dtoPackages>
|
||||
<package>org.eclipse.che.api.devfile.shared.dto</package>
|
||||
</dtoPackages>
|
||||
<outputDirectory>${dto-generator-out-directory}</outputDirectory>
|
||||
<genClassName>org.eclipse.che.api.devfile.server.dto.DtoServerImpls</genClassName>
|
||||
<impl>server</impl>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-compile</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-resource</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>add-resource</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${dto-generator-out-directory}/META-INF</directory>
|
||||
<targetPath>META-INF</targetPath>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${dto-generator-out-directory}</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.shared;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/** Constants for Devfile API */
|
||||
@Beta
|
||||
public final class Constants {
|
||||
public static final String LINK_REL_SELF = "self";
|
||||
|
||||
private Constants() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.shared.dto;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Hyperlinks;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
@DTO
|
||||
@Beta
|
||||
public interface UserDevfileDto extends UserDevfile, Hyperlinks {
|
||||
|
||||
void setId(String id);
|
||||
|
||||
UserDevfileDto withId(String id);
|
||||
|
||||
String getId();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
UserDevfileDto withName(String name);
|
||||
|
||||
String getName();
|
||||
|
||||
void setDescription(String name);
|
||||
|
||||
UserDevfileDto withDescription(String name);
|
||||
|
||||
String getDescription();
|
||||
|
||||
@Override
|
||||
DevfileDto getDevfile();
|
||||
|
||||
void setDevfile(DevfileDto devfile);
|
||||
|
||||
@Override
|
||||
String getNamespace();
|
||||
|
||||
void setNamespace(String namespace);
|
||||
|
||||
UserDevfileDto withNamespace(String namespace);
|
||||
|
||||
UserDevfileDto withDevfile(DevfileDto devfile);
|
||||
|
||||
UserDevfileDto withLinks(List<Link> links);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.shared.event;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventOrigin;
|
||||
|
||||
/** Informs about persisted devfile creation. */
|
||||
@EventOrigin("devfile")
|
||||
@Beta
|
||||
public class DevfileCreatedEvent {
|
||||
private final UserDevfile userDevfile;
|
||||
|
||||
public DevfileCreatedEvent(UserDevfile userDevfile) {
|
||||
this.userDevfile = userDevfile;
|
||||
}
|
||||
|
||||
public UserDevfile getUserDevfile() {
|
||||
return userDevfile;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.shared.event;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.eclipse.che.api.core.notification.EventOrigin;
|
||||
|
||||
/** Informs about persisted devfile removal. */
|
||||
@EventOrigin("devfile")
|
||||
@Beta
|
||||
public class DevfileDeletedEvent {
|
||||
private final String id;
|
||||
|
||||
public DevfileDeletedEvent(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.shared.event;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventOrigin;
|
||||
|
||||
/** Informs about persisted devfile update. */
|
||||
@EventOrigin("devfile")
|
||||
@Beta
|
||||
public class DevfileUpdatedEvent {
|
||||
private final UserDevfile userDevfile;
|
||||
|
||||
public DevfileUpdatedEvent(UserDevfile userDevfile) {
|
||||
this.userDevfile = userDevfile;
|
||||
}
|
||||
|
||||
public UserDevfile getUserDevfile() {
|
||||
return userDevfile;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>che-master-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.20.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Che Core :: API :: Devfile</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-account</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-user</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.restassured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db-vendor-h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-sql-schema</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.jpa</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Create the test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/spi/tck/*.*</include>
|
||||
<include>**/devfile/server/TestObjectGenerator.*</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.devfile.server.DtoConverter.asDto;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_API_VERSION;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
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.Response;
|
||||
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.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.commons.lang.URLEncodedUtils;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
||||
/** Defines Devfile REST API. */
|
||||
@Api(value = "/devfile", description = "Devfile REST API")
|
||||
@Path("/devfile")
|
||||
public class DevfileService extends Service {
|
||||
|
||||
private final DevfileSchemaProvider schemaCachedProvider;
|
||||
private final UserDevfileManager userDevfileManager;
|
||||
private final DevfileServiceLinksInjector linksInjector;
|
||||
|
||||
@Inject
|
||||
public DevfileService(
|
||||
DevfileSchemaProvider schemaCachedProvider,
|
||||
UserDevfileManager userDevfileManager,
|
||||
DevfileServiceLinksInjector linksInjector) {
|
||||
this.userDevfileManager = userDevfileManager;
|
||||
this.linksInjector = linksInjector;
|
||||
this.schemaCachedProvider = schemaCachedProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the json schema.
|
||||
*
|
||||
* @return json schema
|
||||
*/
|
||||
@GET
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Retrieves current version of devfile JSON schema")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The schema successfully retrieved"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public Response getSchema() throws ServerException {
|
||||
try {
|
||||
return Response.ok(schemaCachedProvider.getSchemaContent(CURRENT_API_VERSION)).build();
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/devfile")
|
||||
@POST
|
||||
@Consumes({APPLICATION_JSON, "text/yaml", "text/x-yaml"})
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(
|
||||
value = "Creates a new persistent Devfile from yaml representation",
|
||||
consumes = "application/json, text/yaml, text/x-yaml",
|
||||
produces = APPLICATION_JSON,
|
||||
nickname = "createFromDevfileYaml",
|
||||
response = UserDevfileDto.class)
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 201, message = "The devfile 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 devfile"),
|
||||
@ApiResponse(code = 409, message = "Conflict error occurred during the devfile creation"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public Response createFromDevfileYaml(
|
||||
@ApiParam(value = "The devfile to create", required = true) DevfileDto devfile)
|
||||
throws ConflictException, BadRequestException, ForbiddenException, NotFoundException,
|
||||
ServerException {
|
||||
requiredNotNull(devfile, "Devfile");
|
||||
return Response.status(201)
|
||||
.entity(
|
||||
linksInjector.injectLinks(
|
||||
asDto(
|
||||
userDevfileManager.createDevfile(
|
||||
DtoFactory.newDto(UserDevfileDto.class)
|
||||
.withDevfile(devfile)
|
||||
.withName(NameGenerator.generate("devfile-", 16)))),
|
||||
getServiceContext()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({APPLICATION_JSON})
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(
|
||||
value = "Creates a new persistent Devfile",
|
||||
consumes = "application/json",
|
||||
produces = APPLICATION_JSON,
|
||||
nickname = "create",
|
||||
response = UserDevfileDto.class)
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 201, message = "The devfile 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 devfile"),
|
||||
@ApiResponse(
|
||||
code = 409,
|
||||
message =
|
||||
"Conflict error occurred during the devfile creation"
|
||||
+ "(e.g. The devfile with such name already exists)"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public Response createFromUserDevfile(
|
||||
@ApiParam(value = "The devfile to create", required = true) UserDevfileDto userDevfileDto)
|
||||
throws ConflictException, BadRequestException, ForbiddenException, NotFoundException,
|
||||
ServerException {
|
||||
requiredNotNull(userDevfileDto, "Devfile");
|
||||
return Response.status(201)
|
||||
.entity(
|
||||
linksInjector.injectLinks(
|
||||
asDto(userDevfileManager.createDevfile(userDevfileDto)), getServiceContext()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get devfile by its identifier")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The response contains requested workspace entity"),
|
||||
@ApiResponse(code = 404, message = "The devfile with specified id does not exist"),
|
||||
@ApiResponse(code = 403, message = "The user is not allowed to read devfile"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public UserDevfileDto getById(
|
||||
@ApiParam(value = "UserDevfile identifier") @PathParam("id") String id)
|
||||
throws NotFoundException, ServerException, ForbiddenException, BadRequestException {
|
||||
requiredNotNull(id, "id");
|
||||
return linksInjector.injectLinks(asDto(userDevfileManager.getById(id)), getServiceContext());
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("search")
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(
|
||||
value = "Get devfiles which user can read",
|
||||
notes =
|
||||
"This operation can be performed only by authorized user. "
|
||||
+ "It is possible to add additional constraints for the desired devfiles by specifying\n"
|
||||
+ "multiple query parameters that is representing fields of the devfile. All constrains\n"
|
||||
+ "would be combined with \"And\" condition. Also, it is possible to specify 'like:' prefix\n"
|
||||
+ "for the query parameters. In this case instead of an exact match would be used SQL pattern like search.\n"
|
||||
+ "Examples id=sdfsdf5&devfile.meta.name=like:%dfdf&",
|
||||
response = UserDevfileDto.class,
|
||||
responseContainer = "List")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The devfiles successfully fetched"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred during devfiles fetching")
|
||||
})
|
||||
public Response getUserDevfiles(
|
||||
@ApiParam("The number of the items to skip") @DefaultValue("0") @QueryParam("skipCount")
|
||||
Integer skipCount,
|
||||
@ApiParam("The limit of the items in the response, default is 30, maximum 60")
|
||||
@DefaultValue("30")
|
||||
@QueryParam("maxItems")
|
||||
Integer maxItems,
|
||||
@ApiParam(
|
||||
"A list of fields and directions of sort. By default items would be sorted by id. Example id:asc,name:desc.")
|
||||
@QueryParam("order")
|
||||
String order)
|
||||
throws ServerException, BadRequestException {
|
||||
final Set<String> skip = ImmutableSet.of("token", "skipCount", "maxItems", "order");
|
||||
Map<String, Set<String>> queryParams = URLEncodedUtils.parse(uriInfo.getRequestUri());
|
||||
final List<Pair<String, String>> query =
|
||||
queryParams
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(param -> !param.getValue().isEmpty())
|
||||
.filter(param -> !skip.contains(param.getKey()))
|
||||
.map(entry -> Pair.of(entry.getKey(), entry.getValue().iterator().next()))
|
||||
.collect(toList());
|
||||
List<Pair<String, String>> searchOrder = Collections.emptyList();
|
||||
if (order != null && !order.isEmpty()) {
|
||||
try {
|
||||
searchOrder =
|
||||
Splitter.on(",")
|
||||
.trimResults()
|
||||
.omitEmptyStrings()
|
||||
.withKeyValueSeparator(":")
|
||||
.split(order)
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(e -> Pair.of(e.getKey(), e.getValue()))
|
||||
.collect(toList());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new BadRequestException("Invalid `order` query parameter format." + e.getMessage());
|
||||
}
|
||||
}
|
||||
Page<? extends UserDevfile> userDevfilesPage =
|
||||
userDevfileManager.getUserDevfiles(maxItems, skipCount, query, searchOrder);
|
||||
|
||||
List<UserDevfileDto> list =
|
||||
userDevfilesPage
|
||||
.getItems()
|
||||
.stream()
|
||||
.map(DtoConverter::asDto)
|
||||
.map(dto -> linksInjector.injectLinks(asDto(dto), getServiceContext()))
|
||||
.collect(toList());
|
||||
|
||||
return Response.ok().entity(list).header("Link", createLinkHeader(userDevfilesPage)).build();
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Update the devfile by replacing all the existing data with update")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The devfile 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 devfile"),
|
||||
@ApiResponse(
|
||||
code = 409,
|
||||
message =
|
||||
"Conflict error occurred during devfile update"
|
||||
+ "(e.g. Workspace with such name already exists)"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public UserDevfileDto update(
|
||||
@ApiParam("The devfile id") @PathParam("id") String id,
|
||||
@ApiParam(value = "The devfile update", required = true) UserDevfileDto update)
|
||||
throws BadRequestException, ServerException, ForbiddenException, NotFoundException,
|
||||
ConflictException {
|
||||
requiredNotNull(update, "User Devfile configuration");
|
||||
update.setId(id);
|
||||
return linksInjector.injectLinks(
|
||||
asDto(userDevfileManager.updateUserDevfile(update)), getServiceContext());
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
@ApiOperation(value = "Removes the devfile")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 204, message = "The devfile successfully removed"),
|
||||
@ApiResponse(code = 403, message = "The user does not have access to remove the devfile"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public void delete(@ApiParam("The devfile id") @PathParam("id") String id)
|
||||
throws BadRequestException, ServerException, ForbiddenException {
|
||||
userDevfileManager.removeUserDevfile(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks object reference is not {@code null}
|
||||
*
|
||||
* @param object object reference to check
|
||||
* @param subject used as subject of exception message "{subject} required"
|
||||
* @throws BadRequestException when object reference is {@code null}
|
||||
*/
|
||||
private void requiredNotNull(Object object, String subject) throws BadRequestException {
|
||||
if (object == null) {
|
||||
throw new BadRequestException(subject + " required");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.core.util.LinksHelper;
|
||||
import org.eclipse.che.api.devfile.shared.Constants;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
|
||||
/** Helps to inject {@link DevfileService} related links. */
|
||||
@Beta
|
||||
@Singleton
|
||||
public class DevfileServiceLinksInjector {
|
||||
public UserDevfileDto injectLinks(UserDevfileDto userDevfileDto, ServiceContext serviceContext) {
|
||||
return userDevfileDto.withLinks(
|
||||
ImmutableList.of(
|
||||
LinksHelper.createLink(
|
||||
HttpMethod.GET,
|
||||
serviceContext
|
||||
.getBaseUriBuilder()
|
||||
.clone()
|
||||
.path(DevfileService.class)
|
||||
.path(DevfileService.class, "getById")
|
||||
.build(userDevfileDto.getId())
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
Constants.LINK_REL_SELF)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
|
||||
/** Helps to convert to/from DTOs related to user devfile. */
|
||||
public class DtoConverter {
|
||||
public static UserDevfileDto asDto(UserDevfile userDevfile) {
|
||||
DevfileDto devfileDto =
|
||||
org.eclipse.che.api.workspace.server.DtoConverter.asDto(userDevfile.getDevfile());
|
||||
return newDto(UserDevfileDto.class)
|
||||
.withId(userDevfile.getId())
|
||||
.withDevfile(devfileDto)
|
||||
.withNamespace(userDevfile.getNamespace())
|
||||
.withName(userDevfile.getName())
|
||||
.withDescription(userDevfile.getDescription());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static org.eclipse.che.api.core.Pages.iterate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.account.event.BeforeAccountRemovedEvent;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.core.db.cascade.CascadeEventSubscriber;
|
||||
|
||||
/**
|
||||
* An event listener that is removing all {@link UserDevfile}s that belong to the account that is
|
||||
* going to be removed.
|
||||
*/
|
||||
@Singleton
|
||||
public class RemoveUserDevfileBeforeAccountRemovedEventSubscriber
|
||||
extends CascadeEventSubscriber<BeforeAccountRemovedEvent> {
|
||||
|
||||
private final EventService eventService;
|
||||
private final UserDevfileManager userDevfileManager;
|
||||
|
||||
@Inject
|
||||
public RemoveUserDevfileBeforeAccountRemovedEventSubscriber(
|
||||
EventService eventService, UserDevfileManager userDevfileManager) {
|
||||
this.eventService = eventService;
|
||||
this.userDevfileManager = userDevfileManager;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void subscribe() {
|
||||
eventService.subscribe(this, BeforeAccountRemovedEvent.class);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void unsubscribe() {
|
||||
eventService.unsubscribe(this, BeforeAccountRemovedEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCascadeEvent(BeforeAccountRemovedEvent event) throws Exception {
|
||||
for (UserDevfile userDevfile :
|
||||
iterate(
|
||||
(maxItems, skipCount) ->
|
||||
userDevfileManager.getByNamespace(
|
||||
event.getAccount().getName(), maxItems, skipCount))) {
|
||||
userDevfileManager.removeUserDevfile(userDevfile.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.BadRequestException;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.ext.MessageBodyReader;
|
||||
import javax.ws.rs.ext.MessageBodyWriter;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
||||
/**
|
||||
* Entity provider for {@link UserDevfileDto}. Performs schema validation of devfile part of the
|
||||
* user devfile before actual {@link UserDevfileDto} creation.
|
||||
*/
|
||||
@Singleton
|
||||
@Provider
|
||||
@Produces({APPLICATION_JSON})
|
||||
@Consumes({APPLICATION_JSON})
|
||||
public class UserDevfileEntityProvider
|
||||
implements MessageBodyReader<UserDevfileDto>, MessageBodyWriter<UserDevfileDto> {
|
||||
|
||||
private final DevfileParser devfileParser;
|
||||
private final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Inject
|
||||
public UserDevfileEntityProvider(DevfileParser devfileParser) {
|
||||
this.devfileParser = devfileParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable(
|
||||
Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
|
||||
return type == UserDevfileDto.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDevfileDto readFrom(
|
||||
Class<UserDevfileDto> type,
|
||||
Type genericType,
|
||||
Annotation[] annotations,
|
||||
MediaType mediaType,
|
||||
MultivaluedMap<String, String> httpHeaders,
|
||||
InputStream entityStream)
|
||||
throws IOException, WebApplicationException {
|
||||
try {
|
||||
JsonNode wsNode = mapper.readTree(entityStream);
|
||||
JsonNode devfileNode = wsNode.path("devfile");
|
||||
if (!devfileNode.isNull() && !devfileNode.isMissingNode()) {
|
||||
devfileParser.parseJson(devfileNode.toString());
|
||||
} else {
|
||||
throw new BadRequestException("Mandatory field `devfile` is not defined.");
|
||||
}
|
||||
return DtoFactory.getInstance().createDtoFromJson(wsNode.toString(), UserDevfileDto.class);
|
||||
} catch (DevfileFormatException e) {
|
||||
throw new BadRequestException(e.getMessage());
|
||||
} catch (IOException e) {
|
||||
throw new WebApplicationException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(
|
||||
Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
|
||||
return UserDevfileDto.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize(
|
||||
UserDevfileDto userDevfileDto,
|
||||
Class<?> type,
|
||||
Type genericType,
|
||||
Annotation[] annotations,
|
||||
MediaType mediaType) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(
|
||||
UserDevfileDto userDevfileDto,
|
||||
Class<?> type,
|
||||
Type genericType,
|
||||
Annotation[] annotations,
|
||||
MediaType mediaType,
|
||||
MultivaluedMap<String, Object> httpHeaders,
|
||||
OutputStream entityStream)
|
||||
throws IOException, WebApplicationException {
|
||||
httpHeaders.putSingle(HttpHeaders.CACHE_CONTROL, "public, no-cache, no-store, no-transform");
|
||||
try (Writer w = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) {
|
||||
w.write(DtoFactory.getInstance().toJson(userDevfileDto));
|
||||
w.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.account.api.AccountManager;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.shared.event.DevfileCreatedEvent;
|
||||
import org.eclipse.che.api.devfile.shared.event.DevfileUpdatedEvent;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Facade for {@link UserDevfile} related operations. */
|
||||
@Beta
|
||||
@Singleton
|
||||
public class UserDevfileManager {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UserDevfileManager.class);
|
||||
private final UserDevfileDao userDevfileDao;
|
||||
private final EventService eventService;
|
||||
private final AccountManager accountManager;
|
||||
|
||||
@Inject
|
||||
public UserDevfileManager(
|
||||
AccountManager accountManager, UserDevfileDao userDevfileDao, EventService eventService) {
|
||||
this.accountManager = accountManager;
|
||||
this.userDevfileDao = userDevfileDao;
|
||||
this.eventService = eventService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores {@link Devfile} instance
|
||||
*
|
||||
* @param userDevfile instance of user devfile which would be stored
|
||||
* @return new persisted devfile instance
|
||||
* @throws ConflictException when any conflict occurs (e.g Devfile with such name already exists
|
||||
* for {@code owner})
|
||||
* @throws NullPointerException when {@code devfile} is null
|
||||
* @throws ServerException when any other error occurs
|
||||
*/
|
||||
public UserDevfile createDevfile(UserDevfile userDevfile)
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
requireNonNull(userDevfile, "Required non-null userdevfile");
|
||||
requireNonNull(userDevfile.getDevfile(), "Required non-null devfile");
|
||||
String name =
|
||||
userDevfile.getName() != null
|
||||
? userDevfile.getName()
|
||||
: NameGenerator.generate("devfile-", 5);
|
||||
UserDevfile result =
|
||||
userDevfileDao.create(
|
||||
new UserDevfileImpl(
|
||||
NameGenerator.generate("id-", 16),
|
||||
accountManager.getByName(
|
||||
EnvironmentContext.getCurrent().getSubject().getUserName()),
|
||||
name,
|
||||
userDevfile.getDescription(),
|
||||
userDevfile.getDevfile()));
|
||||
LOG.debug(
|
||||
"UserDevfile '{}' with id '{}' created by user '{}'",
|
||||
result.getName(),
|
||||
result.getId(),
|
||||
EnvironmentContext.getCurrent().getSubject().getUserName());
|
||||
eventService.publish(new DevfileCreatedEvent(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets UserDevfile by given id.
|
||||
*
|
||||
* @param id userdevfile identifier
|
||||
* @return userdevfile instance
|
||||
* @throws NullPointerException when {@code id} is null
|
||||
* @throws NotFoundException when userdevfile with given id not found
|
||||
* @throws ServerException when any server errors occurs
|
||||
*/
|
||||
public UserDevfile getById(String id) throws NotFoundException, ServerException {
|
||||
requireNonNull(id);
|
||||
Optional<UserDevfile> result = userDevfileDao.getById(id);
|
||||
return result.orElseThrow(
|
||||
() -> new NotFoundException(format("Devfile with id '%s' doesn't exist", id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets list of UserDevfiles in given namespace.
|
||||
*
|
||||
* @param namespace devfiles namespace
|
||||
* @return list of devfiles in given namespace. Always returns list(even when there are no devfile
|
||||
* in given namespace), never null
|
||||
* @throws NullPointerException when {@code namespace} is null
|
||||
* @throws ServerException when any other error occurs during workspaces fetching
|
||||
*/
|
||||
public Page<UserDevfile> getByNamespace(String namespace, int maxItems, long skipCount)
|
||||
throws ServerException {
|
||||
requireNonNull(namespace, "Required non-null namespace");
|
||||
final Page<UserDevfile> devfilesPage =
|
||||
userDevfileDao.getByNamespace(namespace, maxItems, skipCount);
|
||||
return devfilesPage;
|
||||
}
|
||||
/**
|
||||
* Updates an existing user devfile in accordance to the new configuration.
|
||||
*
|
||||
* <p>Note: Replace strategy is used for user devfile update, it means that existing devfile data
|
||||
* will be replaced with given {@code update}.
|
||||
*
|
||||
* @param update user devfile update
|
||||
* @return updated user devfile
|
||||
* @throws NullPointerException when {@code update} is null
|
||||
* @throws ConflictException when any conflict occurs.
|
||||
* @throws NotFoundException when user devfile with given id not found
|
||||
* @throws ServerException when any server error occurs
|
||||
*/
|
||||
public UserDevfile updateUserDevfile(UserDevfile update)
|
||||
throws ConflictException, NotFoundException, ServerException {
|
||||
requireNonNull(update);
|
||||
Optional<UserDevfile> result = userDevfileDao.update(update);
|
||||
UserDevfile devfile =
|
||||
result.orElseThrow(
|
||||
() ->
|
||||
new NotFoundException(
|
||||
format("Devfile with id '%s' doesn't exist", update.getId())));
|
||||
LOG.debug(
|
||||
"UserDevfile '{}' with id '{}' update by user '{}'",
|
||||
devfile.getName(),
|
||||
devfile.getId(),
|
||||
EnvironmentContext.getCurrent().getSubject().getUserName());
|
||||
eventService.publish(new DevfileUpdatedEvent(devfile));
|
||||
return devfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stored {@link UserDevfile} by given id.
|
||||
*
|
||||
* @param id user devfile identifier
|
||||
* @throws NullPointerException when {@code id} is null
|
||||
* @throws ServerException when any server errors occurs
|
||||
*/
|
||||
public void removeUserDevfile(String id) throws ServerException {
|
||||
requireNonNull(id);
|
||||
userDevfileDao.remove(id);
|
||||
LOG.debug(
|
||||
"UserDevfile with id '{}' removed by user '{}'",
|
||||
id,
|
||||
EnvironmentContext.getCurrent().getSubject().getUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets list of devfiles. Parameters, returned values and possible exceptions are the same as in
|
||||
* {@link UserDevfileDao#getDevfiles(int, int, List, List)}
|
||||
*/
|
||||
public Page<UserDevfile> getUserDevfiles(
|
||||
int maxItems,
|
||||
int skipCount,
|
||||
List<Pair<String, String>> filter,
|
||||
List<Pair<String, String>> order)
|
||||
throws ServerException {
|
||||
return userDevfileDao.getDevfiles(maxItems, skipCount, filter, order);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server.event;
|
||||
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventOrigin;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.core.db.cascade.event.RemoveEvent;
|
||||
|
||||
/** Published before {@link UserDevfile user devfile} removed. */
|
||||
@EventOrigin("user")
|
||||
public class BeforeDevfileRemovedEvent extends RemoveEvent {
|
||||
|
||||
private final UserDevfileImpl userDevfile;
|
||||
|
||||
public BeforeDevfileRemovedEvent(UserDevfileImpl userDevfile) {
|
||||
this.userDevfile = userDevfile;
|
||||
}
|
||||
|
||||
/** Returns user which is going to be removed. */
|
||||
public UserDevfileImpl getUserDevfile() {
|
||||
return userDevfile;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server.jpa;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.api.devfile.server.jpa.JpaUserDevfileDao.UserDevfileSearchQueryBuilder.newBuilder;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.devfile.server.event.BeforeDevfileRemovedEvent;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
|
||||
import org.eclipse.che.core.db.jpa.IntegrityConstraintViolationException;
|
||||
|
||||
/** JPA based implementation of {@link UserDevfileDao}. */
|
||||
@Singleton
|
||||
@Beta
|
||||
public class JpaUserDevfileDao implements UserDevfileDao {
|
||||
|
||||
protected final Provider<EntityManager> managerProvider;
|
||||
protected final AccountDao accountDao;
|
||||
protected final EventService eventService;
|
||||
/** sorting order that would be used by default during search. */
|
||||
public static final List<Pair<String, String>> DEFAULT_ORDER =
|
||||
ImmutableList.of(new Pair<>("id", "ASC"));
|
||||
/** Set of field that is eligible to use for search. */
|
||||
public static final Set<String> VALID_SEARCH_FIELDS = ImmutableSet.of("name");
|
||||
/** Set of field that is eligible to use for sorting during search. */
|
||||
public static final Set<String> VALID_ORDER_FIELDS = ImmutableSet.of("id", "name");
|
||||
|
||||
@Inject
|
||||
public JpaUserDevfileDao(
|
||||
Provider<EntityManager> managerProvider, AccountDao accountDao, EventService eventService) {
|
||||
this.managerProvider = managerProvider;
|
||||
this.accountDao = accountDao;
|
||||
this.eventService = eventService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDevfile create(UserDevfile userDevfile) throws ConflictException, ServerException {
|
||||
requireNonNull(userDevfile);
|
||||
try {
|
||||
Account account = accountDao.getByName(userDevfile.getNamespace());
|
||||
UserDevfileImpl userDevfileImpl = new UserDevfileImpl(userDevfile, account);
|
||||
doCreate(userDevfileImpl);
|
||||
return userDevfileImpl;
|
||||
} catch (DuplicateKeyException ex) {
|
||||
throw new ConflictException(
|
||||
format(
|
||||
"Devfile with name '%s' already exists in the specified account '%s'",
|
||||
userDevfile.getName(), userDevfile.getNamespace()));
|
||||
} catch (IntegrityConstraintViolationException ex) {
|
||||
throw new ConflictException(
|
||||
"Could not create devfile with creator that refers to a non-existent user");
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ServerException(ex.getMessage(), ex);
|
||||
} catch (NotFoundException e) {
|
||||
throw new ConflictException(
|
||||
format(
|
||||
"Not able to create devfile in requested namespace %s bacause it is not found",
|
||||
userDevfile.getNamespace()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserDevfile> update(UserDevfile userDevfile)
|
||||
throws ConflictException, ServerException, NotFoundException {
|
||||
requireNonNull(userDevfile);
|
||||
try {
|
||||
Account account = accountDao.getByName(userDevfile.getNamespace());
|
||||
return doUpdate(new UserDevfileImpl(userDevfile, account)).map(UserDevfileImpl::new);
|
||||
} catch (DuplicateKeyException ex) {
|
||||
throw new ConflictException(
|
||||
format(
|
||||
"Devfile with name '%s' already exists in current account '%s'",
|
||||
userDevfile.getName(), userDevfile.getNamespace()));
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ServerException(ex.getLocalizedMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String id) throws ServerException {
|
||||
requireNonNull(id);
|
||||
try {
|
||||
doRemove(id);
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ServerException(ex.getLocalizedMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {ServerException.class, RuntimeException.class})
|
||||
public Optional<UserDevfile> getById(String id) throws ServerException {
|
||||
requireNonNull(id);
|
||||
try {
|
||||
final UserDevfileImpl devfile = managerProvider.get().find(UserDevfileImpl.class, id);
|
||||
if (devfile == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(new UserDevfileImpl(devfile));
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ServerException(ex.getLocalizedMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {ServerException.class, RuntimeException.class})
|
||||
@Override
|
||||
public Page<UserDevfile> getByNamespace(String namespace, int maxItems, long skipCount)
|
||||
throws ServerException {
|
||||
requireNonNull(namespace, "Required non-null namespace");
|
||||
try {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
final List<UserDevfileImpl> list =
|
||||
manager
|
||||
.createNamedQuery("UserDevfile.getByNamespace", UserDevfileImpl.class)
|
||||
.setParameter("namespace", namespace)
|
||||
.setMaxResults(maxItems)
|
||||
.setFirstResult((int) skipCount)
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(UserDevfileImpl::new)
|
||||
.collect(Collectors.toList());
|
||||
final long count =
|
||||
manager
|
||||
.createNamedQuery("UserDevfile.getByNamespaceCount", Long.class)
|
||||
.setParameter("namespace", namespace)
|
||||
.getSingleResult();
|
||||
return new Page<>(list, skipCount, maxItems, count);
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {ServerException.class})
|
||||
public Page<UserDevfile> getDevfiles(
|
||||
int maxItems,
|
||||
int skipCount,
|
||||
List<Pair<String, String>> filter,
|
||||
List<Pair<String, String>> order)
|
||||
throws ServerException {
|
||||
|
||||
checkArgument(maxItems > 0, "The number of items has to be positive.");
|
||||
checkArgument(
|
||||
skipCount >= 0,
|
||||
"The number of items to skip can't be negative or greater than " + Integer.MAX_VALUE);
|
||||
|
||||
return doGetDevfiles(
|
||||
maxItems, skipCount, filter, order, () -> newBuilder(managerProvider.get()));
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {ServerException.class})
|
||||
protected Page<UserDevfile> doGetDevfiles(
|
||||
int maxItems,
|
||||
int skipCount,
|
||||
List<Pair<String, String>> filter,
|
||||
List<Pair<String, String>> order,
|
||||
Supplier<UserDevfileSearchQueryBuilder> queryBuilderSupplier)
|
||||
throws ServerException {
|
||||
if (filter != null && !filter.isEmpty()) {
|
||||
List<Pair<String, String>> invalidFilter =
|
||||
filter
|
||||
.stream()
|
||||
.filter(p -> !VALID_SEARCH_FIELDS.contains(p.first.toLowerCase()))
|
||||
.collect(toList());
|
||||
if (!invalidFilter.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Filtering allowed only by " + VALID_SEARCH_FIELDS + " but got: " + invalidFilter);
|
||||
}
|
||||
}
|
||||
List<Pair<String, String>> effectiveOrder = DEFAULT_ORDER;
|
||||
if (order != null && !order.isEmpty()) {
|
||||
List<Pair<String, String>> invalidOrder =
|
||||
order
|
||||
.stream()
|
||||
.filter(p -> !VALID_ORDER_FIELDS.contains(p.first.toLowerCase()))
|
||||
.collect(toList());
|
||||
if (!invalidOrder.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Order allowed only by " + VALID_ORDER_FIELDS + "¬ but got: " + invalidOrder);
|
||||
}
|
||||
|
||||
List<Pair<String, String>> invalidSortOrder =
|
||||
order
|
||||
.stream()
|
||||
.filter(p -> !p.second.equalsIgnoreCase("asc") && !p.second.equalsIgnoreCase("desc"))
|
||||
.collect(Collectors.toList());
|
||||
if (!invalidSortOrder.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid sort order direction. Possible values are 'asc' or 'desc' but got: "
|
||||
+ invalidSortOrder);
|
||||
}
|
||||
effectiveOrder = order;
|
||||
}
|
||||
try {
|
||||
final long count =
|
||||
queryBuilderSupplier.get().withFilter(filter).buildCountQuery().getSingleResult();
|
||||
|
||||
if (count == 0) {
|
||||
return new Page<>(emptyList(), skipCount, maxItems, count);
|
||||
}
|
||||
List<UserDevfileImpl> result =
|
||||
queryBuilderSupplier
|
||||
.get()
|
||||
.withFilter(filter)
|
||||
.withOrder(effectiveOrder)
|
||||
.withMaxItems(maxItems)
|
||||
.withSkipCount(skipCount)
|
||||
.buildSelectItemsQuery()
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(UserDevfileImpl::new)
|
||||
.collect(toList());
|
||||
return new Page<>(result, skipCount, maxItems, count);
|
||||
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public long getTotalCount() throws ServerException {
|
||||
try {
|
||||
return managerProvider
|
||||
.get()
|
||||
.createNamedQuery("UserDevfile.getTotalCount", Long.class)
|
||||
.getSingleResult();
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected void doCreate(UserDevfileImpl devfile) {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
manager.persist(devfile);
|
||||
manager.flush();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected Optional<UserDevfileImpl> doUpdate(UserDevfileImpl update) {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
if (manager.find(UserDevfileImpl.class, update.getId()) == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
UserDevfileImpl merged = manager.merge(update);
|
||||
manager.flush();
|
||||
return Optional.of(merged);
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {RuntimeException.class, ServerException.class})
|
||||
protected void doRemove(String id) throws ServerException {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
final UserDevfileImpl devfile = manager.find(UserDevfileImpl.class, id);
|
||||
if (devfile != null) {
|
||||
eventService
|
||||
.publish(new BeforeDevfileRemovedEvent(new UserDevfileImpl(devfile)))
|
||||
.propagateException();
|
||||
manager.remove(devfile);
|
||||
manager.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public static class UserDevfileSearchQueryBuilder {
|
||||
protected EntityManager entityManager;
|
||||
protected int maxItems;
|
||||
protected int skipCount;
|
||||
protected String filter;
|
||||
protected Map<String, String> params;
|
||||
protected String order;
|
||||
|
||||
public UserDevfileSearchQueryBuilder(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
this.params = new HashMap<>();
|
||||
this.filter = "";
|
||||
this.order = "";
|
||||
}
|
||||
|
||||
public static UserDevfileSearchQueryBuilder newBuilder(EntityManager entityManager) {
|
||||
return new JpaUserDevfileDao.UserDevfileSearchQueryBuilder(entityManager);
|
||||
}
|
||||
|
||||
public UserDevfileSearchQueryBuilder withMaxItems(int maxItems) {
|
||||
this.maxItems = maxItems;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserDevfileSearchQueryBuilder withSkipCount(int skipCount) {
|
||||
this.skipCount = skipCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserDevfileSearchQueryBuilder withFilter(List<Pair<String, String>> filter) {
|
||||
if (filter == null || filter.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
final StringJoiner matcher = new StringJoiner(" AND ", " WHERE ", " ");
|
||||
int i = 0;
|
||||
for (Pair<String, String> attribute : filter) {
|
||||
if (!VALID_SEARCH_FIELDS.contains(attribute.first.toLowerCase())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Filtering allowed only by " + VALID_SEARCH_FIELDS + " but got: " + attribute.first);
|
||||
}
|
||||
final String parameterName = "parameterName" + i++;
|
||||
if (attribute.second.startsWith("like:")) {
|
||||
params.put(parameterName, attribute.second.substring(5));
|
||||
matcher.add("userdevfile." + attribute.first + " LIKE :" + parameterName);
|
||||
} else {
|
||||
params.put(parameterName, attribute.second);
|
||||
matcher.add("userdevfile." + attribute.first + " = :" + parameterName);
|
||||
}
|
||||
}
|
||||
this.filter = matcher.toString();
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserDevfileSearchQueryBuilder withOrder(List<Pair<String, String>> order) {
|
||||
if (order == null || order.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
final StringJoiner matcher = new StringJoiner(", ", " ORDER BY ", " ");
|
||||
for (Pair<String, String> pair : order) {
|
||||
if (!VALID_ORDER_FIELDS.contains(pair.first.toLowerCase())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Order allowed only by " + VALID_ORDER_FIELDS + " but got: " + pair.first);
|
||||
}
|
||||
matcher.add("userdevfile." + pair.first + " " + pair.second);
|
||||
}
|
||||
this.order = matcher.toString();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TypedQuery<Long> buildCountQuery() {
|
||||
StringBuilder query =
|
||||
new StringBuilder()
|
||||
.append("SELECT ")
|
||||
.append(" COUNT(userdevfile) ")
|
||||
.append("FROM UserDevfile userdevfile")
|
||||
.append(filter);
|
||||
TypedQuery<Long> typedQuery = entityManager.createQuery(query.toString(), Long.class);
|
||||
params.forEach((k, v) -> typedQuery.setParameter(k, v));
|
||||
return typedQuery;
|
||||
}
|
||||
|
||||
public TypedQuery<UserDevfileImpl> buildSelectItemsQuery() {
|
||||
|
||||
StringBuilder query =
|
||||
new StringBuilder()
|
||||
.append("SELECT ")
|
||||
.append(" userdevfile ")
|
||||
.append("FROM UserDevfile userdevfile")
|
||||
.append(filter)
|
||||
.append(order);
|
||||
TypedQuery<UserDevfileImpl> typedQuery =
|
||||
entityManager
|
||||
.createQuery(query.toString(), UserDevfileImpl.class)
|
||||
.setFirstResult(skipCount)
|
||||
.setMaxResults(maxItems);
|
||||
params.forEach((k, v) -> typedQuery.setParameter(k, v));
|
||||
return typedQuery;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server.jpa;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.eclipse.che.api.devfile.server.RemoveUserDevfileBeforeAccountRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
|
||||
@Beta
|
||||
public class UserDevfileJpaModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(UserDevfileDao.class).to(JpaUserDevfileDao.class);
|
||||
bind(RemoveUserDevfileBeforeAccountRemovedEventSubscriber.class).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server.model.impl;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import java.util.Objects;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.MetadataImpl;
|
||||
|
||||
@Entity(name = "UserDevfile")
|
||||
@Table(name = "userdevfile")
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "UserDevfile.getByNamespace",
|
||||
query = "SELECT d FROM UserDevfile d WHERE d.account.name = :namespace"),
|
||||
@NamedQuery(
|
||||
name = "UserDevfile.getByNamespaceCount",
|
||||
query = "SELECT COUNT(d) FROM UserDevfile d WHERE d.account.name = :namespace "),
|
||||
@NamedQuery(name = "UserDevfile.getAll", query = "SELECT d FROM UserDevfile d ORDER BY d.id"),
|
||||
@NamedQuery(name = "UserDevfile.getTotalCount", query = "SELECT COUNT(d) FROM UserDevfile d"),
|
||||
})
|
||||
@Beta
|
||||
public class UserDevfileImpl implements UserDevfile {
|
||||
|
||||
/**
|
||||
* In {@MetadataImpl} name is mandatory and generateName is transient. That is not suitable for
|
||||
* UserDevfile because we need to handle situations when the name is not defined and generateName
|
||||
* is defined. To workaround that original name and generateName stored in individual fields
|
||||
* meta_name and meta_generated_name. But at the same time, we can't leave metadata filed null in
|
||||
* devfile because of database hard constrain. To replace that FAKE_META is used.
|
||||
*/
|
||||
private static final MetadataImpl FAKE_META = new MetadataImpl("name");
|
||||
|
||||
@Id
|
||||
@Column(name = "id", nullable = false)
|
||||
private String id;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@JoinColumn(name = "devfile_id")
|
||||
private DevfileImpl devfile;
|
||||
|
||||
@Column(name = "meta_generated_name")
|
||||
private String metaGeneratedName;
|
||||
|
||||
@Column(name = "meta_name")
|
||||
private String metaName;
|
||||
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "accountid", nullable = false)
|
||||
private AccountImpl account;
|
||||
|
||||
public UserDevfileImpl() {}
|
||||
|
||||
public UserDevfileImpl(String id, Account account, UserDevfile userDevfile) {
|
||||
this(
|
||||
id, account, userDevfile.getName(), userDevfile.getDescription(), userDevfile.getDevfile());
|
||||
}
|
||||
|
||||
public UserDevfileImpl(UserDevfile userDevfile, Account account) {
|
||||
this(userDevfile.getId(), account, userDevfile);
|
||||
}
|
||||
|
||||
public UserDevfileImpl(UserDevfileImpl userDevfile) {
|
||||
this(
|
||||
userDevfile.id,
|
||||
userDevfile.account,
|
||||
userDevfile.getName(),
|
||||
userDevfile.getDescription(),
|
||||
userDevfile.getDevfile());
|
||||
}
|
||||
|
||||
public UserDevfileImpl(
|
||||
String id, Account account, String name, String description, Devfile devfile) {
|
||||
this.id = id;
|
||||
this.account = new AccountImpl(account);
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.devfile = new DevfileImpl(devfile);
|
||||
syncMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return account.getName();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Devfile getDevfile() {
|
||||
return new DevfileImpl(
|
||||
devfile.getApiVersion(),
|
||||
devfile.getProjects(),
|
||||
devfile.getComponents(),
|
||||
devfile.getCommands(),
|
||||
devfile.getAttributes(),
|
||||
new MetadataImpl(metaName, metaGeneratedName));
|
||||
}
|
||||
|
||||
public void setDevfile(DevfileImpl devfile) {
|
||||
this.devfile = devfile;
|
||||
syncMeta();
|
||||
}
|
||||
|
||||
public AccountImpl getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(AccountImpl account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
private void syncMeta() {
|
||||
MetadataImpl metadata = devfile.getMetadata();
|
||||
metaGeneratedName = metadata.getGenerateName();
|
||||
metaName = metadata.getName();
|
||||
devfile.setMetadata(FAKE_META);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UserDevfileImpl that = (UserDevfileImpl) o;
|
||||
return Objects.equals(id, that.id)
|
||||
&& Objects.equals(devfile, that.devfile)
|
||||
&& Objects.equals(metaGeneratedName, that.metaGeneratedName)
|
||||
&& Objects.equals(metaName, that.metaName)
|
||||
&& Objects.equals(name, that.name)
|
||||
&& Objects.equals(description, that.description)
|
||||
&& Objects.equals(account, that.account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, devfile, metaGeneratedName, metaName, name, description, account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserDevfileImpl{"
|
||||
+ "id='"
|
||||
+ id
|
||||
+ '\''
|
||||
+ ", devfile="
|
||||
+ devfile
|
||||
+ ", metaGeneratedName='"
|
||||
+ metaGeneratedName
|
||||
+ '\''
|
||||
+ ", metaName='"
|
||||
+ metaName
|
||||
+ '\''
|
||||
+ ", name='"
|
||||
+ name
|
||||
+ '\''
|
||||
+ ", description='"
|
||||
+ description
|
||||
+ '\''
|
||||
+ ", account="
|
||||
+ account
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server.spi;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
|
||||
/** Defines data access object contract for {@code UserDevfileImpl}. */
|
||||
@Beta
|
||||
public interface UserDevfileDao {
|
||||
|
||||
/**
|
||||
* Creates Devfile.
|
||||
*
|
||||
* @param devfile devfile to create
|
||||
* @return created devfile
|
||||
* @throws NullPointerException when {@code devfile} is null
|
||||
* @throws ServerException when any other error occurs
|
||||
* @throws ConflictException when required namespace is not found.
|
||||
*/
|
||||
UserDevfile create(UserDevfile devfile) throws ServerException, ConflictException;
|
||||
|
||||
/**
|
||||
* Updates devfile to the new entity, using replacement strategy.
|
||||
*
|
||||
* @param devfile devfile to update
|
||||
* @return updated devfile
|
||||
* @throws NullPointerException when {@code devfile} is null
|
||||
* @throws ConflictException when any conflict situation occurs
|
||||
* @throws ServerException when any other error occurs
|
||||
*/
|
||||
Optional<UserDevfile> update(UserDevfile devfile)
|
||||
throws ConflictException, ServerException, NotFoundException;
|
||||
|
||||
/**
|
||||
* Removes devfile.
|
||||
*
|
||||
* @param id devfile identifier
|
||||
* @throws NullPointerException when {@code id} is null
|
||||
* @throws ServerException when any other error occurs
|
||||
*/
|
||||
void remove(String id) throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets devfile by identifier.
|
||||
*
|
||||
* @param id devfile identifier
|
||||
* @return devfile instance, never null
|
||||
* @throws NullPointerException when {@code id} is null
|
||||
* @throws ServerException when any other error occurs
|
||||
*/
|
||||
Optional<UserDevfile> getById(String id) throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets list of UserDevfiles in given namespace.
|
||||
*
|
||||
* @param namespace devfiles namespace
|
||||
* @return list of devfiles in given namespace. Always returns list(even when there are no devfile
|
||||
* in given namespace), never null
|
||||
* @throws NullPointerException when {@code namespace} is null
|
||||
* @throws ServerException when any other error occurs during workspaces fetching
|
||||
*/
|
||||
Page<UserDevfile> getByNamespace(String namespace, int maxItems, long skipCount)
|
||||
throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets all devfiles which user can read filtered by given parameters in a given order
|
||||
*
|
||||
* @param maxItems the maximum number of workspaces to return
|
||||
* @param skipCount the number of workspaces to skip
|
||||
* @param filter additional conditions for the desired devfiles. Conditions represented as pairs
|
||||
* of the filed and the value. All pairs would be joined with <b>AND</b> condition. Value of
|
||||
* the pair can start with 'like:' prefix. In this case would be used <i>LIKE</i> query,
|
||||
* otherwise <b>=</b> condition.
|
||||
* @param order - a list of fields and directions of sort. By default items would be sorted by id.
|
||||
* @return list of devfiles which user can read, never null
|
||||
* @throws ServerException when any other error occurs during devfile fetching
|
||||
* @throws IllegalArgumentException when maxItems < 1 or skipCount < 0 or sort order is not 'asc'
|
||||
* or 'desc'.
|
||||
*/
|
||||
Page<UserDevfile> getDevfiles(
|
||||
int maxItems,
|
||||
int skipCount,
|
||||
List<Pair<String, String>> filter,
|
||||
List<Pair<String, String>> order)
|
||||
throws ServerException;
|
||||
|
||||
/**
|
||||
* Get the count of all user devfiles from the persistent layer.
|
||||
*
|
||||
* @return workspace count
|
||||
* @throws ServerException when any error occurs
|
||||
*/
|
||||
long getTotalCount() throws ServerException;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.devfile.shared.Constants;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.everrest.core.impl.uri.UriBuilderImpl;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class DevfileServiceLinksInjectorTest {
|
||||
private static final String URI_BASE = "http://localhost:8080";
|
||||
private static final String SERVICE_PATH = "/devfile";
|
||||
|
||||
@Mock ServiceContext context;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() {
|
||||
final UriBuilder uriBuilder = new UriBuilderImpl();
|
||||
uriBuilder.uri(URI_BASE);
|
||||
|
||||
when(context.getBaseUriBuilder()).thenReturn(uriBuilder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldInjectLinks() {
|
||||
// given
|
||||
final UserDevfileDto userDevfileDto = DtoFactory.newDto(UserDevfileDto.class).withId("id123");
|
||||
DevfileServiceLinksInjector linksInjector = new DevfileServiceLinksInjector();
|
||||
// when
|
||||
final UserDevfileDto withLinks = linksInjector.injectLinks(userDevfileDto, context);
|
||||
// then
|
||||
assertEquals(withLinks.getLinks().size(), 1);
|
||||
assertNotNull(withLinks.getLink(Constants.LINK_REL_SELF));
|
||||
assertEquals(withLinks.getLinks().get(0).getMethod(), HttpMethod.GET);
|
||||
assertEquals(withLinks.getLinks().get(0).getHref(), URI_BASE + SERVICE_PATH + "/id123");
|
||||
assertEquals(withLinks.getLinks().get(0).getProduces(), MediaType.APPLICATION_JSON);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.TEST_ACCOUNT;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.TEST_SUBJECT;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.USER_DEVFILE_ID;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_API_VERSION;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
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.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.jayway.restassured.response.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.core.rest.CheJsonProvider;
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.core.rest.WebApplicationExceptionMapper;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileEntityProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.MetadataDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
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.Mockito;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class DevfileServiceTest {
|
||||
|
||||
@SuppressWarnings("unused") // is declared for deploying by everrest-assured
|
||||
ApiExceptionMapper exceptionMapper = new ApiExceptionMapper();
|
||||
|
||||
WebApplicationExceptionMapper exceptionMapper2 = new WebApplicationExceptionMapper();
|
||||
|
||||
private DevfileSchemaProvider schemaProvider = new DevfileSchemaProvider();
|
||||
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
|
||||
private DevfileParser devfileParser =
|
||||
new DevfileParser(
|
||||
new DevfileSchemaValidator(new DevfileSchemaProvider()),
|
||||
new DevfileIntegrityValidator(Collections.emptyMap()));
|
||||
DevfileEntityProvider devfileEntityProvider = new DevfileEntityProvider(devfileParser);
|
||||
UserDevfileEntityProvider userDevfileEntityProvider =
|
||||
new UserDevfileEntityProvider(devfileParser);
|
||||
private CheJsonProvider jsonProvider = new CheJsonProvider(new HashSet<>());
|
||||
|
||||
@Mock UserDevfileDao userDevfileDao;
|
||||
@Mock UserDevfileManager userDevfileManager;
|
||||
@Mock EventService eventService;
|
||||
@Mock DevfileServiceLinksInjector linksInjector;
|
||||
|
||||
DevfileService userDevfileService;
|
||||
|
||||
@Test
|
||||
public void shouldRetrieveSchema() throws Exception {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
assertEquals(
|
||||
response.getBody().asString(), schemaProvider.getSchemaContent(CURRENT_API_VERSION));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setup() {
|
||||
this.userDevfileService = new DevfileService(schemaProvider, userDevfileManager, linksInjector);
|
||||
lenient()
|
||||
.when(linksInjector.injectLinks(any(UserDevfileDto.class), any(ServiceContext.class)))
|
||||
.thenAnswer((Answer<UserDevfileDto>) invocation -> invocation.getArgument(0));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validUserDevfiles")
|
||||
public void shouldCreateUserDevfileFromJson(UserDevfileDto userDevfileDto) throws Exception {
|
||||
final UserDevfileImpl userDevfileImpl =
|
||||
new UserDevfileImpl("id-123123", TEST_ACCOUNT, userDevfileDto);
|
||||
|
||||
when(userDevfileManager.createDevfile(any(UserDevfile.class))).thenReturn(userDevfileImpl);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(DtoFactory.getInstance().toJson(userDevfileDto))
|
||||
.when()
|
||||
.post(SECURE_PATH + "/devfile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 201);
|
||||
UserDevfileDto dto = unwrapDto(response, UserDevfileDto.class);
|
||||
assertEquals(dto.getNamespace(), TEST_ACCOUNT.getName());
|
||||
assertEquals(new UserDevfileImpl(dto, TEST_ACCOUNT), userDevfileImpl);
|
||||
verify(userDevfileManager).createDevfile(any(UserDevfile.class));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidUserDevfiles")
|
||||
public void shouldFailToCreateInvalidUserDevfileFromJson(
|
||||
UserDevfileDto userDevfileDto, String expectedErrorMessage) throws Exception {
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(DtoFactory.getInstance().toJson(userDevfileDto))
|
||||
.when()
|
||||
.post(SECURE_PATH + "/devfile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
ServiceError error = unwrapDto(response, ServiceError.class);
|
||||
assertNotNull(error);
|
||||
assertEquals(error.getMessage(), expectedErrorMessage);
|
||||
verifyNoMoreInteractions(userDevfileManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetUserDevfileById() throws Exception {
|
||||
final UserDevfileImpl userDevfile = TestObjectGenerator.createUserDevfile();
|
||||
when(userDevfileManager.getById(eq("id-22323"))).thenReturn(userDevfile);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.expect()
|
||||
.statusCode(200)
|
||||
.get(SECURE_PATH + "/devfile/id-22323");
|
||||
|
||||
assertEquals(
|
||||
new UserDevfileImpl(unwrapDto(response, UserDevfileDto.class), TEST_ACCOUNT), userDevfile);
|
||||
verify(userDevfileManager).getById(eq("id-22323"));
|
||||
verify(linksInjector).injectLinks(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowNotFoundExceptionWhenUserDevfileIsNotExistOnGetById() throws Exception {
|
||||
|
||||
final String errMessage = format("UserDevfile with id %s is not found", USER_DEVFILE_ID);
|
||||
doThrow(new NotFoundException(errMessage)).when(userDevfileManager).getById(anyString());
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.expect()
|
||||
.statusCode(404)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile/" + USER_DEVFILE_ID);
|
||||
|
||||
assertEquals(unwrapDto(response, ServiceError.class).getMessage(), errMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowNotFoundExceptionWhenUpdatingNonExistingUserDevfile() throws Exception {
|
||||
// given
|
||||
final UserDevfile userDevfile =
|
||||
DtoConverter.asDto(TestObjectGenerator.createUserDevfile("devfile-name"));
|
||||
|
||||
doThrow(new NotFoundException(format("User devfile with id %s is not found.", USER_DEVFILE_ID)))
|
||||
.when(userDevfileManager)
|
||||
.updateUserDevfile(any(UserDevfile.class));
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType(APPLICATION_JSON)
|
||||
.body(DtoFactory.getInstance().toJson(userDevfile))
|
||||
.when()
|
||||
.put(SECURE_PATH + "/devfile/" + USER_DEVFILE_ID);
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 404);
|
||||
assertEquals(
|
||||
unwrapDto(response, ServiceError.class).getMessage(),
|
||||
format("User devfile with id %s is not found.", USER_DEVFILE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToUpdateUserDevfile() throws Exception {
|
||||
// given
|
||||
final UserDevfileDto devfileDto = TestObjectGenerator.createUserDevfileDto();
|
||||
final UserDevfileImpl userDevfileImpl = new UserDevfileImpl(devfileDto, TEST_ACCOUNT);
|
||||
when(userDevfileManager.updateUserDevfile(any(UserDevfile.class))).thenReturn(userDevfileImpl);
|
||||
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType(APPLICATION_JSON)
|
||||
.body(DtoFactory.getInstance().toJson(devfileDto))
|
||||
.when()
|
||||
.put(SECURE_PATH + "/devfile/" + devfileDto.getId());
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
assertEquals(
|
||||
new UserDevfileImpl(unwrapDto(response, UserDevfileDto.class), TEST_ACCOUNT),
|
||||
userDevfileImpl);
|
||||
verify(userDevfileManager).updateUserDevfile(devfileDto);
|
||||
verify(linksInjector).injectLinks(any(), any());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidUserDevfiles")
|
||||
public void shouldFailToUpdateWithInvalidUserDevfile(
|
||||
UserDevfileDto userDevfileDto, String expectedErrorMessage) throws Exception {
|
||||
// given
|
||||
userDevfileDto = userDevfileDto.withId("id-123");
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType(APPLICATION_JSON)
|
||||
.body(DtoFactory.getInstance().toJson(userDevfileDto))
|
||||
.when()
|
||||
.put(SECURE_PATH + "/devfile/" + userDevfileDto.getId());
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
ServiceError error = unwrapDto(response, ServiceError.class);
|
||||
assertNotNull(error);
|
||||
assertEquals(error.getMessage(), expectedErrorMessage);
|
||||
verifyZeroInteractions(userDevfileManager);
|
||||
verifyZeroInteractions(linksInjector);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldOverrideIdOnUpdateUserDevfile() throws Exception {
|
||||
// given
|
||||
final UserDevfileDto devfileDto = TestObjectGenerator.createUserDevfileDto();
|
||||
final UserDevfileImpl userDevfileImpl = new UserDevfileImpl(devfileDto, TEST_ACCOUNT);
|
||||
|
||||
final String newID = NameGenerator.generate("id", 24);
|
||||
final UserDevfileImpl expectedUserDevfileImpl =
|
||||
new UserDevfileImpl(newID, TEST_ACCOUNT, userDevfileImpl);
|
||||
final UserDevfileDto expectedDto =
|
||||
org.eclipse.che.api.devfile.server.DtoConverter.asDto(expectedUserDevfileImpl);
|
||||
when(userDevfileManager.updateUserDevfile(any(UserDevfile.class)))
|
||||
.thenReturn(expectedUserDevfileImpl);
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType(APPLICATION_JSON)
|
||||
.body(DtoFactory.getInstance().toJson(devfileDto))
|
||||
.when()
|
||||
.put(SECURE_PATH + "/devfile/" + newID);
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
assertEquals(
|
||||
new UserDevfileImpl(unwrapDto(response, UserDevfileDto.class), TEST_ACCOUNT),
|
||||
expectedUserDevfileImpl);
|
||||
verify(userDevfileManager).updateUserDevfile(expectedDto);
|
||||
verify(linksInjector).injectLinks(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveUserDevfileByGivenIdentifier() throws Exception {
|
||||
// given
|
||||
// when
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.expect()
|
||||
.statusCode(204)
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/devfile/" + USER_DEVFILE_ID);
|
||||
// then
|
||||
verify(userDevfileManager).removeUserDevfile(USER_DEVFILE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotThrowAnyExceptionWhenRemovingNonExistingUserDevfile() throws Exception {
|
||||
// given
|
||||
Mockito.doNothing().when(userDevfileManager).removeUserDevfile(anyString());
|
||||
// when
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/devfile/" + USER_DEVFILE_ID);
|
||||
// then
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetUserDevfilesAvailableToUser() throws Exception {
|
||||
// given
|
||||
final UserDevfileDto devfileDto = TestObjectGenerator.createUserDevfileDto();
|
||||
final UserDevfileImpl userDevfileImpl = new UserDevfileImpl(devfileDto, TEST_ACCOUNT);
|
||||
doReturn(new Page<>(ImmutableList.of(userDevfileImpl), 0, 1, 1))
|
||||
.when(userDevfileManager)
|
||||
.getUserDevfiles(anyInt(), anyInt(), anyList(), anyList());
|
||||
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.expect()
|
||||
.statusCode(200)
|
||||
.get(SECURE_PATH + "/devfile/search");
|
||||
// then
|
||||
final List<UserDevfileDto> res = unwrapDtoList(response, UserDevfileDto.class);
|
||||
assertEquals(res.size(), 1);
|
||||
assertEquals(res.get(0).withLinks(emptyList()), devfileDto);
|
||||
verify(userDevfileManager).getUserDevfiles(eq(30), eq(0), anyList(), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToSetLimitAndOffsetOnUserDevfileSearch() throws Exception {
|
||||
// given
|
||||
doReturn(new Page<>(Collections.emptyList(), 0, 1, 0))
|
||||
.when(userDevfileManager)
|
||||
.getUserDevfiles(anyInt(), anyInt(), anyList(), anyList());
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.queryParam("maxItems", 5)
|
||||
.queryParam("skipCount", 52)
|
||||
.when()
|
||||
.expect()
|
||||
.statusCode(200)
|
||||
.get(SECURE_PATH + "/devfile/search");
|
||||
// then
|
||||
verify(userDevfileManager).getUserDevfiles(eq(5), eq(52), anyList(), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToSetFiltertOnUserDevfileSearch() throws Exception {
|
||||
// given
|
||||
doReturn(new Page<>(Collections.emptyList(), 0, 1, 0))
|
||||
.when(userDevfileManager)
|
||||
.getUserDevfiles(anyInt(), anyInt(), anyList(), anyList());
|
||||
Map<String, String> parameters =
|
||||
ImmutableMap.of("id", "sdfsdf5", "devfile.meta.name", "like:%dfdf");
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.queryParameter("id", "sdfsdf5")
|
||||
.queryParameter("devfile.meta.name", "like:%dfdf")
|
||||
.when()
|
||||
.expect()
|
||||
.statusCode(200)
|
||||
.get(SECURE_PATH + "/devfile/search");
|
||||
// then
|
||||
Class<List<Pair<String, String>>> listClass =
|
||||
(Class<List<Pair<String, String>>>) (Class) ArrayList.class;
|
||||
ArgumentCaptor<List<Pair<String, String>>> filterCaptor = ArgumentCaptor.forClass(listClass);
|
||||
verify(userDevfileManager).getUserDevfiles(eq(30), eq(0), filterCaptor.capture(), anyList());
|
||||
assertEquals(
|
||||
filterCaptor.getValue(),
|
||||
ImmutableList.of(new Pair("devfile.meta.name", "like:%dfdf"), new Pair("id", "sdfsdf5")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToSetOrderOnUserDevfileSearch() throws Exception {
|
||||
// given
|
||||
doReturn(new Page<>(Collections.emptyList(), 0, 1, 0))
|
||||
.when(userDevfileManager)
|
||||
.getUserDevfiles(anyInt(), anyInt(), anyList(), anyList());
|
||||
// when
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.queryParameter("order", "id:asc,name:desc")
|
||||
.when()
|
||||
.expect()
|
||||
.statusCode(200)
|
||||
.get(SECURE_PATH + "/devfile/search");
|
||||
// then
|
||||
Class<List<Pair<String, String>>> listClass =
|
||||
(Class<List<Pair<String, String>>>) (Class) ArrayList.class;
|
||||
ArgumentCaptor<List<Pair<String, String>>> orderCaptor = ArgumentCaptor.forClass(listClass);
|
||||
verify(userDevfileManager).getUserDevfiles(eq(30), eq(0), anyList(), orderCaptor.capture());
|
||||
assertEquals(
|
||||
orderCaptor.getValue(), ImmutableList.of(new Pair("id", "asc"), new Pair("name", "desc")));
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] validUserDevfiles() {
|
||||
return new Object[][] {
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name")))
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName(null)
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name")))
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name")))
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withGenerateName("gen-")))
|
||||
},
|
||||
{DtoConverter.asDto(TestObjectGenerator.createUserDevfile())}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] invalidUserDevfiles() {
|
||||
return new Object[][] {
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(null),
|
||||
"Mandatory field `devfile` is not defined."
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion(null)
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name"))),
|
||||
"Devfile schema validation failed. Error: The object must have a property whose name is \"apiVersion\"."
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <T> T unwrapDto(Response response, Class<T> dtoClass) {
|
||||
return DtoFactory.getInstance().createDtoFromJson(response.asString(), dtoClass);
|
||||
}
|
||||
|
||||
private static <T> List<T> unwrapDtoList(Response response, Class<T> dtoClass)
|
||||
throws IOException {
|
||||
return new ArrayList<>(
|
||||
DtoFactory.getInstance().createListDtoFromJson(response.body().asInputStream(), dtoClass));
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(TEST_SUBJECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.MetadataImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.SourceImpl;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
|
||||
public class TestObjectGenerator {
|
||||
|
||||
public static final String TEST_CHE_NAMESPACE = "user";
|
||||
public static final String CURRENT_USER_ID = NameGenerator.generate("usrid", 6);
|
||||
public static final Subject TEST_SUBJECT =
|
||||
new SubjectImpl(TEST_CHE_NAMESPACE, CURRENT_USER_ID, "token", false);
|
||||
public static final String USER_DEVFILE_ID = NameGenerator.generate("usrd", 16);
|
||||
public static final AccountImpl TEST_ACCOUNT =
|
||||
new AccountImpl("acc-id042u3ui3oi", TEST_CHE_NAMESPACE, "test");
|
||||
|
||||
public static UserDevfileDto createUserDevfileDto() {
|
||||
return DtoConverter.asDto(createUserDevfile(NameGenerator.generate("name", 6)));
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile() {
|
||||
return createUserDevfile(NameGenerator.generate("name", 6));
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(String name) {
|
||||
return createUserDevfile(NameGenerator.generate("id", 6), name);
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(String id, String name) {
|
||||
return new UserDevfileImpl(id, TEST_ACCOUNT, name, "devfile description", createDevfile(name));
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(String id, Account account, String name) {
|
||||
return new UserDevfileImpl(id, account, name, "devfile description", createDevfile(name));
|
||||
}
|
||||
|
||||
public static UserDevfileImpl createUserDevfile(Account account) {
|
||||
return createUserDevfile(
|
||||
NameGenerator.generate("id", 6), account, NameGenerator.generate("name", 6));
|
||||
}
|
||||
|
||||
public static DevfileImpl createDevfile(String generatedName) {
|
||||
return createDevfile(null, generatedName);
|
||||
}
|
||||
|
||||
public static DevfileImpl createDevfileWithName(String name) {
|
||||
return createDevfile(name, null);
|
||||
}
|
||||
|
||||
private static DevfileImpl createDevfile(String name, String generatedName) {
|
||||
String effectiveName = MoreObjects.firstNonNull(name, generatedName);
|
||||
SourceImpl source1 =
|
||||
new SourceImpl(
|
||||
"type1",
|
||||
"http://location",
|
||||
"branch1",
|
||||
"point1",
|
||||
"tag1",
|
||||
"commit1",
|
||||
"sparseCheckoutDir1");
|
||||
ProjectImpl project1 = new ProjectImpl("project1", source1, "path1");
|
||||
|
||||
SourceImpl source2 =
|
||||
new SourceImpl(
|
||||
"type2",
|
||||
"http://location",
|
||||
"branch2",
|
||||
"point2",
|
||||
"tag2",
|
||||
"commit2",
|
||||
"sparseCheckoutDir2");
|
||||
ProjectImpl project2 = new ProjectImpl("project2", source2, "path2");
|
||||
|
||||
ActionImpl action1 =
|
||||
new ActionImpl("exec1", "component1", "run.sh", "/home/user/1", null, null);
|
||||
ActionImpl action2 =
|
||||
new ActionImpl("exec2", "component2", "run.sh", "/home/user/2", null, null);
|
||||
|
||||
CommandImpl command1 =
|
||||
new CommandImpl(
|
||||
effectiveName + "-1", singletonList(action1), singletonMap("attr1", "value1"), null);
|
||||
CommandImpl command2 =
|
||||
new CommandImpl(
|
||||
effectiveName + "-2", singletonList(action2), singletonMap("attr2", "value2"), null);
|
||||
|
||||
EntrypointImpl entrypoint1 =
|
||||
new EntrypointImpl(
|
||||
"parentName1",
|
||||
singletonMap("parent1", "selector1"),
|
||||
"containerName1",
|
||||
asList("command1", "command2"),
|
||||
asList("arg1", "arg2"));
|
||||
|
||||
EntrypointImpl entrypoint2 =
|
||||
new EntrypointImpl(
|
||||
"parentName2",
|
||||
singletonMap("parent2", "selector2"),
|
||||
"containerName2",
|
||||
asList("command3", "command4"),
|
||||
asList("arg3", "arg4"));
|
||||
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl volume1 =
|
||||
new org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl("name1", "path1");
|
||||
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl volume2 =
|
||||
new org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl("name2", "path2");
|
||||
|
||||
EnvImpl env1 = new EnvImpl("name1", "value1");
|
||||
EnvImpl env2 = new EnvImpl("name2", "value2");
|
||||
|
||||
EndpointImpl endpoint1 = new EndpointImpl("name1", 1111, singletonMap("key1", "value1"));
|
||||
EndpointImpl endpoint2 = new EndpointImpl("name2", 2222, singletonMap("key2", "value2"));
|
||||
|
||||
ComponentImpl component1 =
|
||||
new ComponentImpl(
|
||||
"kubernetes",
|
||||
"component1",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"refcontent1",
|
||||
ImmutableMap.of("app.kubernetes.io/component", "db"),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
asList(env1, env2),
|
||||
null);
|
||||
component1.setSelector(singletonMap("key1", "value1"));
|
||||
|
||||
ComponentImpl component2 =
|
||||
new ComponentImpl(
|
||||
"dockerimage",
|
||||
"component2",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"image",
|
||||
"256G",
|
||||
null,
|
||||
"3",
|
||||
"180m",
|
||||
false,
|
||||
false,
|
||||
singletonList("command"),
|
||||
singletonList("arg"),
|
||||
asList(volume1, volume2),
|
||||
asList(env1, env2),
|
||||
asList(endpoint1, endpoint2));
|
||||
ComponentImpl component3 =
|
||||
new ComponentImpl(
|
||||
"chePlugin",
|
||||
"check/terminal-sample/0.0.1",
|
||||
ImmutableMap.of(
|
||||
"java.home",
|
||||
"/home/user/jdk11aertwertert",
|
||||
"java.boolean",
|
||||
"true",
|
||||
"java.long",
|
||||
"123444L"));
|
||||
MetadataImpl metadata = new MetadataImpl(name);
|
||||
metadata.setGenerateName(generatedName);
|
||||
DevfileImpl devfile =
|
||||
new DevfileImpl(
|
||||
"1.0.0",
|
||||
asList(project1, project2),
|
||||
asList(component1, component2, component3),
|
||||
asList(command1, command2),
|
||||
singletonMap("attribute1", "value1"),
|
||||
metadata);
|
||||
|
||||
return devfile;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.TEST_ACCOUNT;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.TEST_CHE_NAMESPACE;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.createUserDevfile;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import org.eclipse.che.account.api.AccountManager;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.shared.event.DevfileCreatedEvent;
|
||||
import org.eclipse.che.api.devfile.shared.event.DevfileDeletedEvent;
|
||||
import org.eclipse.che.api.devfile.shared.event.DevfileUpdatedEvent;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(value = MockitoTestNGListener.class)
|
||||
public class UserDevfileManagerTest {
|
||||
@Mock UserDevfileDao userDevfileDao;
|
||||
@Mock EventService eventService;
|
||||
@Mock AccountManager accountManager;
|
||||
@InjectMocks UserDevfileManager userDevfileManager;
|
||||
|
||||
@Captor private ArgumentCaptor<UserDevfileImpl> userDevfileArgumentCaptor;
|
||||
@Captor private ArgumentCaptor<DevfileCreatedEvent> devfileCreatedEventCaptor;
|
||||
@Captor private ArgumentCaptor<DevfileDeletedEvent> devfileDeletedEventCaptor;
|
||||
@Captor private ArgumentCaptor<DevfileUpdatedEvent> devfileUpdatedEventCaptor;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
EnvironmentContext.getCurrent().setSubject(TestObjectGenerator.TEST_SUBJECT);
|
||||
lenient().doReturn(TEST_ACCOUNT).when(accountManager).getByName(eq(TEST_CHE_NAMESPACE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateUserDevfileIdOnCreation() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile =
|
||||
new UserDevfileImpl(null, TEST_ACCOUNT, createUserDevfile());
|
||||
when(userDevfileDao.create(any(UserDevfileImpl.class)))
|
||||
.thenAnswer(invocationOnMock -> invocationOnMock.getArguments()[0]);
|
||||
// when
|
||||
UserDevfile actual = userDevfileManager.createDevfile(userDevfile);
|
||||
// then
|
||||
verify(userDevfileDao).create(userDevfileArgumentCaptor.capture());
|
||||
assertFalse(isNullOrEmpty(userDevfileArgumentCaptor.getValue().getId()));
|
||||
assertEquals(new UserDevfileImpl(null, TEST_ACCOUNT, actual), userDevfile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSendDevfileCreatedEventOnCreation() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile =
|
||||
new UserDevfileImpl(null, TEST_ACCOUNT, createUserDevfile());
|
||||
when(userDevfileDao.create(any(UserDevfileImpl.class)))
|
||||
.thenAnswer(invocationOnMock -> invocationOnMock.getArguments()[0]);
|
||||
// when
|
||||
UserDevfile expected = userDevfileManager.createDevfile(userDevfile);
|
||||
// then
|
||||
verify(eventService).publish(devfileCreatedEventCaptor.capture());
|
||||
assertEquals(expected, devfileCreatedEventCaptor.getValue().getUserDevfile());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenGettingUserDevfileByNullId() throws Exception {
|
||||
userDevfileManager.getById(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetUserDevfileById() throws Exception {
|
||||
// given
|
||||
final Optional<UserDevfile> toFetch = Optional.of(createUserDevfile());
|
||||
when(userDevfileDao.getById(eq("id123"))).thenReturn(toFetch);
|
||||
|
||||
// when
|
||||
final UserDevfile fetched = userDevfileManager.getById("id123");
|
||||
// then
|
||||
assertEquals(fetched, toFetch.get());
|
||||
verify(userDevfileDao).getById("id123");
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = NotFoundException.class,
|
||||
expectedExceptionsMessageRegExp = "Devfile with id 'id123' doesn't exist")
|
||||
public void shouldThrowNotFoundExceptionOnGetUserDevfileByIdIfNotFound() throws Exception {
|
||||
// given
|
||||
doReturn(Optional.empty()).when(userDevfileDao).getById(eq("id123"));
|
||||
// when
|
||||
userDevfileManager.getById("id123");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenUpdatingUserDevfileByNullId() throws Exception {
|
||||
userDevfileManager.updateUserDevfile(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateUserDevfile() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile = createUserDevfile();
|
||||
when(userDevfileDao.update(any(UserDevfileImpl.class)))
|
||||
.thenAnswer(invocationOnMock -> Optional.of(invocationOnMock.getArguments()[0]));
|
||||
// when
|
||||
userDevfileManager.updateUserDevfile(userDevfile);
|
||||
// then
|
||||
verify(userDevfileDao).update(eq(userDevfile));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class)
|
||||
public void shouldThrowNotFoundIfUserDevfileIsNotFoundOnUpdate() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile = createUserDevfile();
|
||||
Mockito.doReturn(Optional.empty()).when(userDevfileDao).update(any(UserDevfileImpl.class));
|
||||
// when
|
||||
userDevfileManager.updateUserDevfile(userDevfile);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhendeleteUserDevfileByNullId() throws Exception {
|
||||
userDevfileManager.removeUserDevfile(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveUserDevfile() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile = createUserDevfile();
|
||||
// when
|
||||
userDevfileManager.removeUserDevfile(userDevfile.getId());
|
||||
// then
|
||||
verify(userDevfileDao).remove(userDevfile.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSendDevfileUpdatedEventOnUpdateDevfile() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile = createUserDevfile();
|
||||
when(userDevfileDao.update(any(UserDevfileImpl.class)))
|
||||
.thenAnswer(invocationOnMock -> Optional.of(invocationOnMock.getArguments()[0]));
|
||||
// when
|
||||
userDevfileManager.updateUserDevfile(userDevfile);
|
||||
// then
|
||||
verify(eventService).publish(devfileUpdatedEventCaptor.capture());
|
||||
assertEquals(userDevfile, devfileUpdatedEventCaptor.getValue().getUserDevfile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetUserDevfilesAvailableToUser() throws ServerException {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile = createUserDevfile();
|
||||
final UserDevfileImpl userDevfile2 = createUserDevfile();
|
||||
when(userDevfileDao.getDevfiles(2, 30, Collections.emptyList(), Collections.emptyList()))
|
||||
.thenReturn(new Page<>(asList(userDevfile, userDevfile2), 0, 2, 2));
|
||||
// when
|
||||
Page<UserDevfile> actual =
|
||||
userDevfileManager.getUserDevfiles(2, 30, Collections.emptyList(), Collections.emptyList());
|
||||
// then
|
||||
assertEquals(actual.getItems().size(), 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server.jpa;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.account.spi.jpa.JpaAccountDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.SourceImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
import org.eclipse.che.commons.test.db.PersistTestModuleBuilder;
|
||||
import org.eclipse.che.commons.test.tck.TckModule;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.commons.test.tck.repository.JpaTckRepository;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.eclipse.che.core.db.DBInitializer;
|
||||
import org.eclipse.che.core.db.h2.jpa.eclipselink.H2ExceptionHandler;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializer;
|
||||
import org.eclipse.che.core.db.schema.impl.flyway.FlywaySchemaInitializer;
|
||||
import org.h2.Driver;
|
||||
|
||||
/** Tck module for UserDevfile test. */
|
||||
public class UserDevfileTckModule extends TckModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
H2DBTestServer server = H2DBTestServer.startDefault();
|
||||
install(
|
||||
new PersistTestModuleBuilder()
|
||||
.setDriver(Driver.class)
|
||||
.runningOn(server)
|
||||
.addEntityClasses(
|
||||
UserImpl.class,
|
||||
AccountImpl.class,
|
||||
UserDevfileImpl.class,
|
||||
DevfileImpl.class,
|
||||
ActionImpl.class,
|
||||
CommandImpl.class,
|
||||
ComponentImpl.class,
|
||||
DevfileImpl.class,
|
||||
EndpointImpl.class,
|
||||
EntrypointImpl.class,
|
||||
EnvImpl.class,
|
||||
ProjectImpl.class,
|
||||
SourceImpl.class,
|
||||
VolumeImpl.class)
|
||||
.addClass(SerializableConverter.class)
|
||||
.setExceptionHandler(H2ExceptionHandler.class)
|
||||
.setProperty("eclipselink.logging.level", "OFF")
|
||||
.build());
|
||||
bind(DBInitializer.class).asEagerSingleton();
|
||||
bind(SchemaInitializer.class)
|
||||
.toInstance(new FlywaySchemaInitializer(server.getDataSource(), "che-schema"));
|
||||
bind(TckResourcesCleaner.class).toInstance(new H2JpaCleaner(server));
|
||||
|
||||
bind(UserDevfileDao.class).to(JpaUserDevfileDao.class);
|
||||
bind(AccountDao.class).to(JpaAccountDao.class);
|
||||
|
||||
bind(new TypeLiteral<TckRepository<UserDevfileImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfileImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<UserImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<AccountImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(AccountImpl.class));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,589 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server.spi.tck;
|
||||
|
||||
import static java.lang.Math.min;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.createUserDevfile;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.persistence.EntityManager;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.devfile.UserDevfile;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.devfile.server.TestObjectGenerator;
|
||||
import org.eclipse.che.api.devfile.server.event.BeforeDevfileRemovedEvent;
|
||||
import org.eclipse.che.api.devfile.server.jpa.JpaUserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.MetadataImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.SourceImpl;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.commons.test.tck.TckListener;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(TckListener.class)
|
||||
@Test(suiteName = UserDevfileDaoTest.SUITE_NAME)
|
||||
public class UserDevfileDaoTest {
|
||||
|
||||
public static final String SUITE_NAME = "DevfileDaoTck";
|
||||
private static final int ENTRY_COUNT = 10;
|
||||
private static final int COUNT_OF_ACCOUNTS = 6;
|
||||
|
||||
private UserDevfileImpl[] devfiles;
|
||||
private AccountImpl[] accounts;
|
||||
|
||||
@Inject private EventService eventService;
|
||||
|
||||
@Inject private UserDevfileDao userDevfileDaoDao;
|
||||
|
||||
@Inject private TckRepository<UserDevfileImpl> devfileTckRepository;
|
||||
|
||||
@Inject private TckRepository<UserImpl> userTckRepository;
|
||||
|
||||
@Inject private TckRepository<AccountImpl> accountRepo;
|
||||
|
||||
@Inject private Provider<EntityManager> entityManagerProvider;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
accounts = new AccountImpl[COUNT_OF_ACCOUNTS];
|
||||
for (int i = 0; i < COUNT_OF_ACCOUNTS; i++) {
|
||||
accounts[i] = new AccountImpl("accountId" + i, "accountName" + i, "test");
|
||||
}
|
||||
|
||||
devfiles = new UserDevfileImpl[ENTRY_COUNT];
|
||||
for (int i = 0; i < ENTRY_COUNT; i++) {
|
||||
AccountImpl account = accounts[i / 2];
|
||||
devfiles[i] =
|
||||
createUserDevfile(
|
||||
NameGenerator.generate("id-" + i + "-", 6),
|
||||
account,
|
||||
NameGenerator.generate("devfileName-" + i, 6));
|
||||
}
|
||||
accountRepo.createAll(Stream.of(accounts).map(AccountImpl::new).collect(toList()));
|
||||
devfileTckRepository.createAll(Stream.of(devfiles).map(UserDevfileImpl::new).collect(toList()));
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanUp() throws Exception {
|
||||
devfileTckRepository.removeAll();
|
||||
accountRepo.removeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetUserDevfileById() throws Exception {
|
||||
final UserDevfileImpl devfile = devfiles[0];
|
||||
|
||||
assertEquals(userDevfileDaoDao.getById(devfile.getId()), Optional.of(devfile));
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "shouldGetUserDevfileById")
|
||||
public void shouldCreateUserDevfile() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl devfile = createUserDevfile(accounts[0]);
|
||||
// when
|
||||
userDevfileDaoDao.create(devfile);
|
||||
|
||||
assertEquals(
|
||||
userDevfileDaoDao.getById(devfile.getId()), Optional.of(new UserDevfileImpl(devfile)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateUserDevfileWithNullDescription() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl devfile = createUserDevfile(accounts[0]);
|
||||
devfile.setDescription(null);
|
||||
// when
|
||||
userDevfileDaoDao.create(devfile);
|
||||
|
||||
Optional<UserDevfile> devfileOptional = userDevfileDaoDao.getById(devfile.getId());
|
||||
assertTrue(devfileOptional.isPresent());
|
||||
assertNull(devfileOptional.get().getDescription());
|
||||
assertEquals(devfileOptional, Optional.of(new UserDevfileImpl(devfile)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateUserDevfileWithEmptyMataName() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl devfile = createUserDevfile(accounts[0]);
|
||||
DevfileImpl newDevfile = new DevfileImpl(devfile.getDevfile());
|
||||
MetadataImpl newMeta = new MetadataImpl();
|
||||
newMeta.setGenerateName("gener-");
|
||||
newDevfile.setMetadata(newMeta);
|
||||
devfile.setDevfile(newDevfile);
|
||||
// when
|
||||
userDevfileDaoDao.create(devfile);
|
||||
|
||||
Optional<UserDevfile> devfileOptional = userDevfileDaoDao.getById(devfile.getId());
|
||||
assertTrue(devfileOptional.isPresent());
|
||||
UserDevfile actual = devfileOptional.get();
|
||||
assertNull(actual.getDevfile().getMetadata().getName());
|
||||
assertNotNull(actual.getDevfile().getMetadata().getGenerateName());
|
||||
assertEquals(devfileOptional, Optional.of(new UserDevfileImpl(devfile)));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenCreateNullDevfile() throws Exception {
|
||||
userDevfileDaoDao.create(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ConflictException.class)
|
||||
public void shouldThrowConflictExceptionWhenCreatingUserDevfileWithExistingId() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl devfile = createUserDevfile(accounts[0]);
|
||||
final UserDevfileImpl existing = devfiles[0];
|
||||
devfile.setId(existing.getId());
|
||||
// when
|
||||
userDevfileDaoDao.create(devfile);
|
||||
// then
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateUserDevfile() throws Exception {
|
||||
// given
|
||||
|
||||
DevfileImpl newDevfile = TestObjectGenerator.createDevfile("newUpdate");
|
||||
newDevfile.setApiVersion("V15.0");
|
||||
newDevfile.setProjects(
|
||||
ImmutableList.of(
|
||||
new ProjectImpl(
|
||||
"projectUp2",
|
||||
new SourceImpl(
|
||||
"typeUp2",
|
||||
"http://location",
|
||||
"branch2",
|
||||
"point2",
|
||||
"tag2",
|
||||
"commit2",
|
||||
"sparseCheckoutDir2"),
|
||||
"path2")));
|
||||
newDevfile.setComponents(ImmutableList.of(new ComponentImpl("type3", "id54")));
|
||||
newDevfile.setCommands(
|
||||
ImmutableList.of(
|
||||
new CommandImpl(
|
||||
new CommandImpl(
|
||||
"cmd1",
|
||||
Collections.singletonList(
|
||||
new ActionImpl(
|
||||
"exe44", "compo2nent2", "run.sh", "/home/user/2", null, null)),
|
||||
Collections.singletonMap("attr1", "value1"),
|
||||
null))));
|
||||
newDevfile.setAttributes(ImmutableMap.of("key2", "val34"));
|
||||
newDevfile.setMetadata(new MetadataImpl("myNewName"));
|
||||
final UserDevfileImpl update = devfiles[0];
|
||||
update.setDevfile(newDevfile);
|
||||
// when
|
||||
userDevfileDaoDao.update(update);
|
||||
// then
|
||||
assertEquals(userDevfileDaoDao.getById(update.getId()), Optional.of(update));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotUpdateWorkspaceWhichDoesNotExist() throws Exception {
|
||||
// given
|
||||
final UserDevfileImpl userDevfile = devfiles[0];
|
||||
userDevfile.setId("non-existing-devfile");
|
||||
// when
|
||||
Optional<UserDevfile> result = userDevfileDaoDao.update(userDevfile);
|
||||
// then
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenUpdatingNull() throws Exception {
|
||||
userDevfileDaoDao.update(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenGetByIdNull() throws Exception {
|
||||
userDevfileDaoDao.getById(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenDeleteNull() throws Exception {
|
||||
userDevfileDaoDao.getById(null);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "shouldGetUserDevfileById")
|
||||
public void shouldRemoveDevfile() throws Exception {
|
||||
final String userDevfileId = devfiles[0].getId();
|
||||
userDevfileDaoDao.remove(userDevfileId);
|
||||
Optional<UserDevfile> result = userDevfileDaoDao.getById(userDevfileId);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDoNothingWhenRemovingNonExistingUserDevfile() throws Exception {
|
||||
userDevfileDaoDao.remove("non-existing");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetAvailableToUserDevfiles() throws ServerException {
|
||||
// given
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(30, 0, Collections.emptyList(), Collections.emptyList());
|
||||
// then
|
||||
assertEquals(new HashSet<>(result.getItems()), new HashSet<>(asList(devfiles)));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void shouldThrowIllegalStateExceptionOnNegativeLimit() throws Exception {
|
||||
userDevfileDaoDao.getDevfiles(0, -2, Collections.emptyList(), Collections.emptyList());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void shouldThrowIllegalStateExceptionOnNegativeSkipCount() throws Exception {
|
||||
userDevfileDaoDao.getDevfiles(-2, 0, Collections.emptyList(), Collections.emptyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetAvailableToUserDevfilesWithFilter() throws ServerException {
|
||||
// given
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
30,
|
||||
0,
|
||||
ImmutableList.of(new Pair<>("name", "like:devfileName%")),
|
||||
Collections.emptyList());
|
||||
// then
|
||||
assertEquals(new HashSet<>(result.getItems()), new HashSet<>(asList(devfiles)));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void shouldNotAllowSearchWithInvalidFilter() throws ServerException {
|
||||
// given
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
30,
|
||||
0,
|
||||
ImmutableList.of(
|
||||
new Pair<>("id", "like:dev%"),
|
||||
new Pair<>("devfile.metadata.something", "like:devfileName%")),
|
||||
Collections.emptyList());
|
||||
// then
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetAvailableToUserDevfilesWithFilter2()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
final UserDevfileImpl update = devfiles[0];
|
||||
update.setName("New345Name");
|
||||
userDevfileDaoDao.update(update);
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
30, 0, ImmutableList.of(new Pair<>("name", "like:%w345N%")), Collections.emptyList());
|
||||
// then
|
||||
assertEquals(new HashSet<>(result.getItems()), ImmutableSet.of(update));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetAvailableToUserDevfilesWithFilterAndLimit()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
final UserDevfileImpl update = devfiles[0];
|
||||
update.setName("New345Name");
|
||||
userDevfileDaoDao.update(update);
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
12,
|
||||
0,
|
||||
ImmutableList.of(new Pair<>("name", "like:devfileName%")),
|
||||
Collections.emptyList());
|
||||
// then
|
||||
assertEquals(result.getItems().size(), 9);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetDevfilesSortedById()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
UserDevfileImpl[] expected =
|
||||
Arrays.stream(devfiles)
|
||||
.sorted(Comparator.comparing(UserDevfileImpl::getId))
|
||||
.toArray(UserDevfileImpl[]::new);
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
devfiles.length, 0, Collections.emptyList(), ImmutableList.of(new Pair<>("id", "asc")));
|
||||
// then
|
||||
assertEquals(result.getItems().stream().toArray(UserDevfileImpl[]::new), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetDevfilesSortedByIdReverse()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
UserDevfileImpl[] expected =
|
||||
Arrays.stream(devfiles)
|
||||
.sorted(Comparator.comparing(UserDevfileImpl::getId).reversed())
|
||||
.toArray(UserDevfileImpl[]::new);
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
devfiles.length,
|
||||
0,
|
||||
Collections.emptyList(),
|
||||
ImmutableList.of(new Pair<>("id", "desc")));
|
||||
// then
|
||||
assertEquals(result.getItems().stream().toArray(UserDevfileImpl[]::new), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetDevfilesSortedByName()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
UserDevfileImpl[] expected =
|
||||
Arrays.stream(devfiles)
|
||||
.sorted(Comparator.comparing(UserDevfileImpl::getName))
|
||||
.toArray(UserDevfileImpl[]::new);
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
devfiles.length,
|
||||
0,
|
||||
Collections.emptyList(),
|
||||
ImmutableList.of(new Pair<>("name", "asc")));
|
||||
// then
|
||||
assertEquals(result.getItems().stream().toArray(UserDevfileImpl[]::new), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSendDevfileDeletedEventOnRemoveUserDevfile() throws Exception {
|
||||
// given
|
||||
final String userDevfileId = devfiles[0].getId();
|
||||
final boolean[] isNotified = new boolean[] {false};
|
||||
eventService.subscribe(event -> isNotified[0] = true, BeforeDevfileRemovedEvent.class);
|
||||
// when
|
||||
userDevfileDaoDao.remove(userDevfileId);
|
||||
// then
|
||||
assertTrue(isNotified[0], "Event subscriber notified");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "boundsdataprovider")
|
||||
public void shouldBeAbleToGetDevfilesSortedByNameWithSpecificMaxItemsAndSkipCount(
|
||||
int maxitems, int skipCount) throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
UserDevfileImpl[] expected =
|
||||
Arrays.stream(
|
||||
Arrays.copyOfRange(devfiles, skipCount, min(devfiles.length, skipCount + maxitems)))
|
||||
.sorted(Comparator.comparing(UserDevfileImpl::getId))
|
||||
.toArray(UserDevfileImpl[]::new);
|
||||
// when
|
||||
final Page<UserDevfile> result =
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
maxitems,
|
||||
skipCount,
|
||||
Collections.emptyList(),
|
||||
ImmutableList.of(new Pair<>("id", "asc")));
|
||||
// then
|
||||
assertEquals(result.getItems().stream().toArray(UserDevfileImpl[]::new), expected);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boundsdataprovider() {
|
||||
return new Object[][] {
|
||||
{1, 1},
|
||||
{1, 4},
|
||||
{4, 5},
|
||||
{6, 8},
|
||||
{1, ENTRY_COUNT},
|
||||
{ENTRY_COUNT, ENTRY_COUNT},
|
||||
{ENTRY_COUNT, 1},
|
||||
{ENTRY_COUNT, 8}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = IllegalArgumentException.class,
|
||||
expectedExceptionsMessageRegExp = "The number of items has to be positive.")
|
||||
public void shouldNotAllowZeroMaxItemsToSearch()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
// when
|
||||
userDevfileDaoDao.getDevfiles(0, 0, Collections.emptyList(), Collections.emptyList());
|
||||
// then
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = IllegalArgumentException.class,
|
||||
expectedExceptionsMessageRegExp = "The number of items has to be positive.")
|
||||
public void shouldNotAllowNegativeMaxItemsToSearch()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
// when
|
||||
userDevfileDaoDao.getDevfiles(-5, 0, Collections.emptyList(), Collections.emptyList());
|
||||
// then
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = IllegalArgumentException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"The number of items to skip can't be negative or greater than 2147483647")
|
||||
public void shouldNotAllowNegativeItemsToSkipToSearch()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
// when
|
||||
userDevfileDaoDao.getDevfiles(5, -1, Collections.emptyList(), Collections.emptyList());
|
||||
// then
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = IllegalArgumentException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Invalid sort order direction\\. Possible values are 'asc' or 'desc'"
|
||||
+ " but got: \\[\\{first=name, second=ddd}, \\{first=id, second=bla}]")
|
||||
public void shouldFailOnInvalidSortOrder()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
// given
|
||||
// when
|
||||
userDevfileDaoDao.getDevfiles(
|
||||
5,
|
||||
4,
|
||||
Collections.emptyList(),
|
||||
ImmutableList.of(
|
||||
new Pair<>("id", "asc"),
|
||||
new Pair<>("name", "ddd"),
|
||||
new Pair<>("name", "DesC"),
|
||||
new Pair<>("id", "bla")));
|
||||
// then
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetDevfilesByNamespace() throws Exception {
|
||||
final UserDevfileImpl devfile1 = devfiles[0];
|
||||
final UserDevfileImpl devfile2 = devfiles[1];
|
||||
assertEquals(devfile1.getNamespace(), devfile2.getNamespace(), "Namespaces must be the same");
|
||||
|
||||
final Page<UserDevfile> found = userDevfileDaoDao.getByNamespace(devfile1.getNamespace(), 6, 0);
|
||||
|
||||
assertEquals(found.getTotalItemsCount(), 2);
|
||||
assertEquals(found.getItemsCount(), 2);
|
||||
assertEquals(new HashSet<>(found.getItems()), new HashSet<>(asList(devfile1, devfile2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyListShouldBeReturnedWhenThereAreNoDevfilesInGivenNamespace() throws Exception {
|
||||
assertTrue(userDevfileDaoDao.getByNamespace("non-existing-namespace", 30, 0).isEmpty());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenGettingDevfilesByNullNamespace() throws Exception {
|
||||
userDevfileDaoDao.getByNamespace(null, 30, 0);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validOrderFiled")
|
||||
public void shouldTestValidOrderFileds(String filed) {
|
||||
JpaUserDevfileDao.UserDevfileSearchQueryBuilder queryBuilder =
|
||||
new JpaUserDevfileDao.UserDevfileSearchQueryBuilder(null);
|
||||
try {
|
||||
queryBuilder.withOrder(ImmutableList.of(new Pair<>(filed, "blah")));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail(filed + " is valid but failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Test(
|
||||
dataProvider = "invalidOrderField",
|
||||
expectedExceptions = IllegalArgumentException.class,
|
||||
expectedExceptionsMessageRegExp = "Order allowed only by \\[id, name\\] but got: .*")
|
||||
public void shouldTestInvalidOrderFileds(String filed) {
|
||||
JpaUserDevfileDao.UserDevfileSearchQueryBuilder queryBuilder =
|
||||
new JpaUserDevfileDao.UserDevfileSearchQueryBuilder(null);
|
||||
queryBuilder.withOrder(ImmutableList.of(new Pair<>(filed, "blah")));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validSearchFiled")
|
||||
public void shouldTestValidSearchFileds(String filed) {
|
||||
JpaUserDevfileDao.UserDevfileSearchQueryBuilder queryBuilder =
|
||||
new JpaUserDevfileDao.UserDevfileSearchQueryBuilder(null);
|
||||
try {
|
||||
queryBuilder.withFilter(ImmutableList.of(new Pair<>(filed, "blah")));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail(filed + " is valid but failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Test(
|
||||
dataProvider = "invalidSearchField",
|
||||
expectedExceptions = IllegalArgumentException.class,
|
||||
expectedExceptionsMessageRegExp = "Filtering allowed only by \\[name\\] but got: .*")
|
||||
public void shouldTestInvalidSearchFileds(String filed) {
|
||||
JpaUserDevfileDao.UserDevfileSearchQueryBuilder queryBuilder =
|
||||
new JpaUserDevfileDao.UserDevfileSearchQueryBuilder(null);
|
||||
queryBuilder.withFilter(ImmutableList.of(new Pair<>(filed, "blah")));
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] validOrderFiled() {
|
||||
return new Object[][] {{"id"}, {"Id"}, {"name"}, {"nAmE"}};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] invalidOrderField() {
|
||||
return new Object[][] {{"devfile"}, {"meta_name"}, {"description"}, {"meta_generated_name"}};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] validSearchFiled() {
|
||||
return new Object[][] {
|
||||
{"name"}, {"NaMe"},
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] invalidSearchField() {
|
||||
return new Object[][] {
|
||||
{"id"}, {"devfile"}, {"ID"}, {"meta_name"}, {"description"}, {"meta_generated_name"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.che.api.devfile.server.jpa.UserDevfileTckModule
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
|
|
@ -64,7 +64,7 @@ public class JpaFactoryDao implements FactoryDao {
|
|||
format("Factory with name '%s' already exists for current user", factory.getName()));
|
||||
} catch (IntegrityConstraintViolationException ex) {
|
||||
throw new ConflictException(
|
||||
"Could not create factory with creator that refers on non-existent user");
|
||||
"Could not create factory with creator that refers to a non-existent user");
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ServerException(ex.getLocalizedMessage(), ex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import org.eclipse.che.api.core.BadRequestException;
|
|||
import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl.DevfileLocation;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.server.DtoConverter;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileManager;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
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.exception.DevfileException;
|
||||
|
|
@ -53,18 +53,18 @@ public class URLFactoryBuilder {
|
|||
private final String defaultChePlugins;
|
||||
|
||||
private final URLFetcher urlFetcher;
|
||||
private final DevfileManager devfileManager;
|
||||
private final DevfileParser devfileParser;
|
||||
|
||||
@Inject
|
||||
public URLFactoryBuilder(
|
||||
@Named("che.factory.default_editor") String defaultCheEditor,
|
||||
@Named("che.factory.default_plugins") String defaultChePlugins,
|
||||
URLFetcher urlFetcher,
|
||||
DevfileManager devfileManager) {
|
||||
DevfileParser devfileParser) {
|
||||
this.defaultCheEditor = defaultCheEditor;
|
||||
this.defaultChePlugins = defaultChePlugins;
|
||||
this.urlFetcher = urlFetcher;
|
||||
this.devfileManager = devfileManager;
|
||||
this.devfileParser = devfileParser;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,8 +115,8 @@ public class URLFactoryBuilder {
|
|||
continue;
|
||||
}
|
||||
try {
|
||||
DevfileImpl devfile = devfileManager.parseYaml(devfileYamlContent, overrideProperties);
|
||||
devfileManager.resolveReference(devfile, fileContentProvider);
|
||||
DevfileImpl devfile = devfileParser.parseYaml(devfileYamlContent, overrideProperties);
|
||||
devfileParser.resolveReference(devfile, fileContentProvider);
|
||||
devfile = ensureToUseGenerateName(devfile);
|
||||
|
||||
FactoryDto factoryDto =
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import java.util.Map;
|
|||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileManager;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
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.devfile.schema.DevfileSchemaProvider;
|
||||
|
|
@ -76,10 +76,10 @@ public class DefaultFactoryParameterResolverTest {
|
|||
|
||||
DevfileIntegrityValidator integrityValidator = new DevfileIntegrityValidator(validators);
|
||||
|
||||
DevfileManager devfileManager = new DevfileManager(validator, integrityValidator);
|
||||
DevfileParser devfileParser = new DevfileParser(validator, integrityValidator);
|
||||
|
||||
URLFactoryBuilder factoryBuilder =
|
||||
new URLFactoryBuilder("editor", "plugin", urlFetcher, devfileManager);
|
||||
new URLFactoryBuilder("editor", "plugin", urlFetcher, devfileParser);
|
||||
|
||||
DefaultFactoryParameterResolver res =
|
||||
new DefaultFactoryParameterResolver(factoryBuilder, urlFetcher);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import org.eclipse.che.api.core.BadRequestException;
|
|||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl.DevfileLocation;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileManager;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
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.exception.DevfileException;
|
||||
|
|
@ -68,7 +68,7 @@ public class URLFactoryBuilderTest {
|
|||
/** Grab content of URLs */
|
||||
@Mock private URLFetcher urlFetcher;
|
||||
|
||||
@Mock private DevfileManager devfileManager;
|
||||
@Mock private DevfileParser devfileParser;
|
||||
|
||||
/** Tested instance. */
|
||||
private URLFactoryBuilder urlFactoryBuilder;
|
||||
|
|
@ -76,7 +76,7 @@ public class URLFactoryBuilderTest {
|
|||
@BeforeClass
|
||||
public void setUp() {
|
||||
this.urlFactoryBuilder =
|
||||
new URLFactoryBuilder(defaultEditor, defaultPlugin, urlFetcher, devfileManager);
|
||||
new URLFactoryBuilder(defaultEditor, defaultPlugin, urlFetcher, devfileParser);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -132,7 +132,7 @@ public class URLFactoryBuilderTest {
|
|||
workspaceConfigImpl.setDefaultEnv("name");
|
||||
|
||||
when(urlFetcher.fetchSafely(anyString())).thenReturn("random_content");
|
||||
when(devfileManager.parseYaml(anyString(), anyMap())).thenReturn(devfile);
|
||||
when(devfileParser.parseYaml(anyString(), anyMap())).thenReturn(devfile);
|
||||
|
||||
FactoryDto factory =
|
||||
urlFactoryBuilder
|
||||
|
|
@ -192,7 +192,7 @@ public class URLFactoryBuilderTest {
|
|||
return "http://foo.bar/anything";
|
||||
}
|
||||
}));
|
||||
when(devfileManager.parseYaml(anyString(), anyMap())).thenReturn(devfile);
|
||||
when(devfileParser.parseYaml(anyString(), anyMap())).thenReturn(devfile);
|
||||
when(urlFetcher.fetchSafely(anyString())).thenReturn("anything");
|
||||
FactoryDto factory =
|
||||
urlFactoryBuilder
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import javax.ws.rs.core.MultivaluedMap;
|
|||
import javax.ws.rs.ext.MessageBodyReader;
|
||||
import javax.ws.rs.ext.MessageBodyWriter;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileManager;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
|
|
@ -54,12 +54,12 @@ import org.eclipse.che.dto.server.DtoFactory;
|
|||
public class WorkspaceEntityProvider
|
||||
implements MessageBodyReader<WorkspaceDto>, MessageBodyWriter<WorkspaceDto> {
|
||||
|
||||
private DevfileManager devfileManager;
|
||||
private DevfileParser devfileParser;
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Inject
|
||||
public WorkspaceEntityProvider(DevfileManager devfileManager) {
|
||||
this.devfileManager = devfileManager;
|
||||
public WorkspaceEntityProvider(DevfileParser devfileParser) {
|
||||
this.devfileParser = devfileParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -81,7 +81,7 @@ public class WorkspaceEntityProvider
|
|||
JsonNode wsNode = mapper.readTree(entityStream);
|
||||
JsonNode devfileNode = wsNode.path("devfile");
|
||||
if (!devfileNode.isNull() && !devfileNode.isMissingNode()) {
|
||||
devfileManager.parseJson(devfileNode.toString());
|
||||
devfileParser.parseJson(devfileNode.toString());
|
||||
}
|
||||
return DtoFactory.getInstance().createDtoFromJson(wsNode.toString(), WorkspaceDto.class);
|
||||
} catch (DevfileFormatException e) {
|
||||
|
|
|
|||
|
|
@ -55,11 +55,11 @@ import org.eclipse.che.dto.server.DtoFactory;
|
|||
public class DevfileEntityProvider
|
||||
implements MessageBodyReader<DevfileDto>, MessageBodyWriter<DevfileDto> {
|
||||
|
||||
private DevfileManager devfileManager;
|
||||
private DevfileParser devfileParser;
|
||||
|
||||
@Inject
|
||||
public DevfileEntityProvider(DevfileManager devfileManager) {
|
||||
this.devfileManager = devfileManager;
|
||||
public DevfileEntityProvider(DevfileParser devfileParser) {
|
||||
this.devfileParser = devfileParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -81,13 +81,13 @@ public class DevfileEntityProvider
|
|||
try {
|
||||
if (mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)) {
|
||||
return asDto(
|
||||
devfileManager.parseJson(
|
||||
devfileParser.parseJson(
|
||||
CharStreams.toString(
|
||||
new InputStreamReader(entityStream, getCharsetOrUtf8(mediaType)))));
|
||||
} else if (mediaType.isCompatible(MediaType.valueOf("text/yaml"))
|
||||
|| mediaType.isCompatible(MediaType.valueOf("text/x-yaml"))) {
|
||||
return asDto(
|
||||
devfileManager.parseYaml(
|
||||
devfileParser.parseYaml(
|
||||
CharStreams.toString(
|
||||
new InputStreamReader(entityStream, getCharsetOrUtf8(mediaType)))));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ public class DevfileModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DevfileService.class);
|
||||
bind(DevfileEntityProvider.class);
|
||||
|
||||
DevfileBindings.onWorkspaceApplierBinder(
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
|||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class DevfileManager {
|
||||
public class DevfileParser {
|
||||
|
||||
private ObjectMapper yamlMapper;
|
||||
private ObjectMapper jsonMapper;
|
||||
|
|
@ -54,7 +54,7 @@ public class DevfileManager {
|
|||
private final OverridePropertiesApplier overridePropertiesApplier;
|
||||
|
||||
@Inject
|
||||
public DevfileManager(
|
||||
public DevfileParser(
|
||||
DevfileSchemaValidator schemaValidator, DevfileIntegrityValidator integrityValidator) {
|
||||
this(
|
||||
schemaValidator,
|
||||
|
|
@ -64,7 +64,7 @@ public class DevfileManager {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DevfileManager(
|
||||
DevfileParser(
|
||||
DevfileSchemaValidator schemaValidator,
|
||||
DevfileIntegrityValidator integrityValidator,
|
||||
ObjectMapper yamlMapper,
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.workspace.server.devfile;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_API_VERSION;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Response;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
|
||||
@Api(value = "/devfile", description = "Devfile REST API")
|
||||
@Path("/devfile")
|
||||
public class DevfileService extends Service {
|
||||
|
||||
private DevfileSchemaProvider schemaCachedProvider;
|
||||
|
||||
@Inject
|
||||
public DevfileService(DevfileSchemaProvider schemaCachedProvider) {
|
||||
this.schemaCachedProvider = schemaCachedProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the json schema.
|
||||
*
|
||||
* @return json schema
|
||||
*/
|
||||
@GET
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Retrieves current version of devfile JSON schema")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The schema successfully retrieved"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public Response getSchema() throws ServerException {
|
||||
try {
|
||||
return Response.ok(schemaCachedProvider.getSchemaContent(CURRENT_API_VERSION)).build();
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,11 @@ public class MetadataImpl implements Metadata {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public MetadataImpl(String name, String generateName) {
|
||||
this.name = name;
|
||||
this.generateName = generateName;
|
||||
}
|
||||
|
||||
public MetadataImpl(Metadata metadata) {
|
||||
this.name = metadata.getName();
|
||||
this.generateName = metadata.getGenerateName();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileManager;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
|
|
@ -34,14 +34,14 @@ import org.testng.annotations.Test;
|
|||
@Listeners(MockitoTestNGListener.class)
|
||||
public class WorkspaceEntityProviderTest {
|
||||
|
||||
@Mock private DevfileManager devfileManager;
|
||||
@Mock private DevfileParser devfileParser;
|
||||
|
||||
@InjectMocks private WorkspaceEntityProvider workspaceEntityProvider;
|
||||
|
||||
@Test
|
||||
public void shouldBuildDtoFromValidJson() throws Exception {
|
||||
|
||||
when(devfileManager.parseJson(anyString())).thenReturn(new DevfileImpl());
|
||||
when(devfileParser.parseJson(anyString())).thenReturn(new DevfileImpl());
|
||||
|
||||
WorkspaceDto actual = newDto(WorkspaceDto.class).withDevfile(newDto(DevfileDto.class));
|
||||
|
||||
|
|
@ -54,6 +54,6 @@ public class WorkspaceEntityProviderTest {
|
|||
new ByteArrayInputStream(
|
||||
DtoFactory.getInstance().toJson(actual).getBytes(StandardCharsets.UTF_8)));
|
||||
|
||||
verify(devfileManager).parseJson(anyString());
|
||||
verify(devfileParser).parseJson(anyString());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,12 @@ import org.eclipse.che.api.core.model.workspace.runtime.ServerStatus;
|
|||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.core.rest.CheJsonProvider;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileEntityProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
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.MachineConfigImpl;
|
||||
|
|
@ -139,6 +144,13 @@ public class WorkspaceServiceTest {
|
|||
@SuppressWarnings("unused") // is declared for deploying by everrest-assured
|
||||
private CheJsonProvider jsonProvider = new CheJsonProvider(Collections.emptySet());
|
||||
|
||||
@SuppressWarnings("unused") // is declared for deploying by everrest-assured
|
||||
private DevfileEntityProvider devfileEntityProvider =
|
||||
new DevfileEntityProvider(
|
||||
new DevfileParser(
|
||||
new DevfileSchemaValidator(new DevfileSchemaProvider()),
|
||||
new DevfileIntegrityValidator(Collections.emptyMap())));
|
||||
|
||||
@Mock private WorkspaceManager wsManager;
|
||||
@Mock private MachineTokenProvider machineTokenProvider;
|
||||
@Mock private WorkspaceLinksGenerator linksGenerator;
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ import org.testng.annotations.Test;
|
|||
@Listeners(MockitoTestNGListener.class)
|
||||
public class DevfileEntityProviderTest {
|
||||
|
||||
@Mock private DevfileManager devfileManager;
|
||||
@Mock private DevfileParser devfileParser;
|
||||
|
||||
@InjectMocks private DevfileEntityProvider devfileEntityProvider;
|
||||
|
||||
@Test
|
||||
public void shouldBuildDtoFromValidYaml() throws Exception {
|
||||
|
||||
when(devfileManager.parseYaml(anyString())).thenReturn(new DevfileImpl());
|
||||
when(devfileParser.parseYaml(anyString())).thenReturn(new DevfileImpl());
|
||||
|
||||
devfileEntityProvider.readFrom(
|
||||
DevfileDto.class,
|
||||
|
|
@ -46,13 +46,13 @@ public class DevfileEntityProviderTest {
|
|||
new MultivaluedHashMap<>(),
|
||||
getClass().getClassLoader().getResourceAsStream("devfile/devfile.yaml"));
|
||||
|
||||
verify(devfileManager).parseYaml(anyString());
|
||||
verify(devfileParser).parseYaml(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBuildDtoFromValidJson() throws Exception {
|
||||
|
||||
when(devfileManager.parseJson(anyString())).thenReturn(new DevfileImpl());
|
||||
when(devfileParser.parseJson(anyString())).thenReturn(new DevfileImpl());
|
||||
|
||||
devfileEntityProvider.readFrom(
|
||||
DevfileDto.class,
|
||||
|
|
@ -62,7 +62,7 @@ public class DevfileEntityProviderTest {
|
|||
new MultivaluedHashMap<>(),
|
||||
getClass().getClassLoader().getResourceAsStream("devfile/devfile.json"));
|
||||
|
||||
verify(devfileManager).parseJson(anyString());
|
||||
verify(devfileParser).parseJson(anyString());
|
||||
}
|
||||
|
||||
@Test(
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import org.testng.annotations.Listeners;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class DevfileManagerTest {
|
||||
public class DevfileParserTest {
|
||||
|
||||
private static final String DEVFILE_YAML_CONTENT = "devfile yaml stub";
|
||||
|
||||
|
|
@ -56,13 +56,12 @@ public class DevfileManagerTest {
|
|||
@Mock private JsonNode devfileJsonNode;
|
||||
private DevfileImpl devfile;
|
||||
|
||||
private DevfileManager devfileManager;
|
||||
private DevfileParser devfileParser;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
devfile = new DevfileImpl();
|
||||
devfileManager =
|
||||
new DevfileManager(schemaValidator, integrityValidator, yamlMapper, jsonMapper);
|
||||
devfileParser = new DevfileParser(schemaValidator, integrityValidator, yamlMapper, jsonMapper);
|
||||
|
||||
lenient().when(jsonMapper.treeToValue(any(), eq(DevfileImpl.class))).thenReturn(devfile);
|
||||
lenient().when(yamlMapper.treeToValue(any(), eq(DevfileImpl.class))).thenReturn(devfile);
|
||||
|
|
@ -72,7 +71,7 @@ public class DevfileManagerTest {
|
|||
@Test
|
||||
public void testValidateAndParse() throws Exception {
|
||||
// when
|
||||
DevfileImpl parsed = devfileManager.parseYaml(DEVFILE_YAML_CONTENT);
|
||||
DevfileImpl parsed = devfileParser.parseYaml(DEVFILE_YAML_CONTENT);
|
||||
|
||||
// then
|
||||
assertEquals(parsed, devfile);
|
||||
|
|
@ -93,7 +92,7 @@ public class DevfileManagerTest {
|
|||
devfile.getComponents().add(component);
|
||||
|
||||
// when
|
||||
DevfileImpl parsed = devfileManager.parseYaml(DEVFILE_YAML_CONTENT);
|
||||
DevfileImpl parsed = devfileParser.parseYaml(DEVFILE_YAML_CONTENT);
|
||||
|
||||
// then
|
||||
assertNotNull(parsed.getCommands().get(0).getAttributes());
|
||||
|
|
@ -113,7 +112,7 @@ public class DevfileManagerTest {
|
|||
devfile.getComponents().add(component);
|
||||
|
||||
// when
|
||||
devfileManager.resolveReference(devfile, contentProvider);
|
||||
devfileParser.resolveReference(devfile, contentProvider);
|
||||
|
||||
// then
|
||||
verify(contentProvider).fetchContent(eq("myfile.yaml"));
|
||||
|
|
@ -125,7 +124,7 @@ public class DevfileManagerTest {
|
|||
expectedExceptionsMessageRegExp = "Unable to parse Devfile - provided source is empty")
|
||||
public void shouldThrowDevfileExceptionWhenEmptyObjectProvided() throws Exception {
|
||||
// when
|
||||
devfileManager.parseJson("{}");
|
||||
devfileParser.parseJson("{}");
|
||||
}
|
||||
|
||||
@Test(
|
||||
|
|
@ -133,7 +132,7 @@ public class DevfileManagerTest {
|
|||
expectedExceptionsMessageRegExp = "Unable to parse Devfile - provided source is empty")
|
||||
public void shouldThrowDevfileExceptionWhenEmptySourceProvided() throws Exception {
|
||||
// when
|
||||
devfileManager.parseJson("");
|
||||
devfileParser.parseJson("");
|
||||
}
|
||||
|
||||
@Test(
|
||||
|
|
@ -150,7 +149,7 @@ public class DevfileManagerTest {
|
|||
devfile.getComponents().add(component);
|
||||
|
||||
// when
|
||||
devfileManager.resolveReference(devfile, contentProvider);
|
||||
devfileParser.resolveReference(devfile, contentProvider);
|
||||
|
||||
// then exception is thrown
|
||||
}
|
||||
|
|
@ -163,7 +162,7 @@ public class DevfileManagerTest {
|
|||
doThrow(new DevfileFormatException("non valid")).when(schemaValidator).validate(any());
|
||||
|
||||
// when
|
||||
devfileManager.parseYaml(DEVFILE_YAML_CONTENT);
|
||||
devfileParser.parseYaml(DEVFILE_YAML_CONTENT);
|
||||
}
|
||||
|
||||
@Test(
|
||||
|
|
@ -177,6 +176,6 @@ public class DevfileManagerTest {
|
|||
doThrow(jsonException).when(jsonMapper).treeToValue(any(), any());
|
||||
|
||||
// when
|
||||
devfileManager.parseJson(DEVFILE_YAML_CONTENT);
|
||||
devfileParser.parseJson(DEVFILE_YAML_CONTENT);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.workspace.server.devfile;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_API_VERSION;
|
||||
import static org.everrest.assured.JettyHttpServer.*;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import com.jayway.restassured.response.Response;
|
||||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class DevfileServiceTest {
|
||||
|
||||
@SuppressWarnings("unused") // is declared for deploying by everrest-assured
|
||||
private ApiExceptionMapper exceptionMapper;
|
||||
|
||||
private DevfileSchemaProvider schemaProvider = new DevfileSchemaProvider();
|
||||
|
||||
private static final Subject SUBJECT = new SubjectImpl("user", "user123", "token", false);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private DevfileService devFileService;
|
||||
|
||||
@BeforeMethod
|
||||
public void initService() {
|
||||
this.devFileService = new DevfileService(schemaProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRetrieveSchema() throws Exception {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
assertEquals(
|
||||
response.getBody().asString(), schemaProvider.getSchemaContent(CURRENT_API_VERSION));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
--
|
||||
-- Copyright (c) 2012-2020 Red Hat, Inc.
|
||||
-- This program and the accompanying materials are made
|
||||
-- available under the terms of the Eclipse Public License 2.0
|
||||
-- which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
--
|
||||
-- SPDX-License-Identifier: EPL-2.0
|
||||
--
|
||||
-- Contributors:
|
||||
-- Red Hat, Inc. - initial API and implementation
|
||||
--
|
||||
|
||||
|
||||
-- add userdevfile table
|
||||
CREATE TABLE userdevfile (
|
||||
id VARCHAR(255) NOT NULL UNIQUE,
|
||||
accountid VARCHAR(255) NOT NULL,
|
||||
devfile_id BIGINT NOT NULL UNIQUE,
|
||||
meta_generated_name VARCHAR(255) ,
|
||||
meta_name VARCHAR(255) ,
|
||||
name VARCHAR(255) NOT NULL ,
|
||||
description TEXT ,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE INDEX index_userdevfile_devfile_id ON userdevfile (devfile_id);
|
||||
CREATE INDEX index_userdevfile_name ON userdevfile(name);
|
||||
ALTER TABLE userdevfile ADD CONSTRAINT unq_userdevfile_0 UNIQUE (name, accountid);
|
||||
ALTER TABLE userdevfile ADD CONSTRAINT fx_userdevfile_accountid FOREIGN KEY (accountid) REFERENCES account (id);
|
||||
ALTER TABLE userdevfile ADD CONSTRAINT fk_userdevfile_devfile_id FOREIGN KEY (devfile_id) REFERENCES devfile (id);
|
||||
|
|
@ -90,6 +90,17 @@
|
|||
<artifactId>che-core-api-account</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import javax.persistence.EntityManager;
|
|||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.account.spi.jpa.JpaAccountDao;
|
||||
import org.eclipse.che.api.devfile.server.jpa.JpaUserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.ssh.server.jpa.JpaSshDao;
|
||||
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
|
||||
import org.eclipse.che.api.ssh.server.spi.SshDao;
|
||||
|
|
@ -135,6 +138,7 @@ public class MySqlTckModule extends TckModule {
|
|||
SignatureKeyImpl.class,
|
||||
SignatureKeyPairImpl.class,
|
||||
// devfile
|
||||
UserDevfileImpl.class,
|
||||
ActionImpl.class,
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl.class,
|
||||
ComponentImpl.class,
|
||||
|
|
@ -196,6 +200,10 @@ public class MySqlTckModule extends TckModule {
|
|||
bind(WorkspaceActivityDao.class).to(JpaWorkspaceActivityDao.class);
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {}).toInstance(new WorkspaceRepository());
|
||||
|
||||
bind(UserDevfileDao.class).to(JpaUserDevfileDao.class);
|
||||
bind(new TypeLiteral<TckRepository<UserDevfileImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfileImpl.class));
|
||||
|
||||
// sign keys
|
||||
bind(SignatureKeyDao.class).to(JpaSignatureKeyDao.class);
|
||||
bind(new TypeLiteral<TckRepository<SignatureKeyPairImpl>>() {})
|
||||
|
|
|
|||
|
|
@ -80,6 +80,17 @@
|
|||
<artifactId>che-core-api-account</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import javax.persistence.EntityManager;
|
|||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.account.spi.jpa.JpaAccountDao;
|
||||
import org.eclipse.che.api.devfile.server.jpa.JpaUserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.server.model.impl.UserDevfileImpl;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.ssh.server.jpa.JpaSshDao;
|
||||
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
|
||||
import org.eclipse.che.api.ssh.server.spi.SshDao;
|
||||
|
|
@ -130,6 +133,7 @@ public class PostgreSqlTckModule extends TckModule {
|
|||
WorkspaceActivity.class,
|
||||
VolumeImpl.class,
|
||||
// devfile
|
||||
UserDevfileImpl.class,
|
||||
ActionImpl.class,
|
||||
org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl.class,
|
||||
ComponentImpl.class,
|
||||
|
|
@ -191,6 +195,9 @@ public class PostgreSqlTckModule extends TckModule {
|
|||
bind(WorkspaceActivityDao.class).to(JpaWorkspaceActivityDao.class);
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {}).toInstance(new WorkspaceRepository());
|
||||
|
||||
bind(UserDevfileDao.class).to(JpaUserDevfileDao.class);
|
||||
bind(new TypeLiteral<TckRepository<UserDevfileImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserDevfileImpl.class));
|
||||
// k8s runtimes
|
||||
bind(new TypeLiteral<TckRepository<KubernetesRuntimeState>>() {})
|
||||
.toInstance(new JpaTckRepository<>(KubernetesRuntimeState.class));
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
<module>che-core-api-workspace</module>
|
||||
<module>che-core-api-workspace-activity</module>
|
||||
<module>che-core-api-user-shared</module>
|
||||
<module>che-core-api-devfile-shared</module>
|
||||
<module>che-core-api-devfile</module>
|
||||
<module>che-core-api-account</module>
|
||||
<module>che-core-api-user</module>
|
||||
<module>che-core-api-factory-shared</module>
|
||||
|
|
|
|||
Loading…
Reference in New Issue