Remove Stack service (#14078)
* Remove Che6 Stack concept Signed-off-by: Sergii Kabashniuk <skabashniuk@redhat.com>7.20.x
parent
3da8646eaf
commit
40ee503a05
|
|
@ -73,7 +73,6 @@ import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceAgentJava
|
|||
import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceIdEnvVarProvider;
|
||||
import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceNameEnvVarProvider;
|
||||
import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceNamespaceNameEnvVarProvider;
|
||||
import org.eclipse.che.api.workspace.server.stack.StackLoader;
|
||||
import org.eclipse.che.api.workspace.server.token.MachineTokenProvider;
|
||||
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
|
||||
import org.eclipse.che.commons.auth.token.ChainedTokenExtractor;
|
||||
|
|
@ -156,12 +155,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
|
||||
install(new DevfileModule());
|
||||
|
||||
MapBinder<String, String> stacks =
|
||||
MapBinder.newMapBinder(
|
||||
binder(), String.class, String.class, Names.named(StackLoader.CHE_PREDEFINED_STACKS));
|
||||
stacks.addBinding("stacks.json").toInstance("stacks-images");
|
||||
stacks.addBinding("che-in-che.json").toInstance("");
|
||||
bind(org.eclipse.che.api.workspace.server.stack.StackService.class);
|
||||
bind(org.eclipse.che.api.workspace.server.TemporaryWorkspaceRemover.class);
|
||||
bind(org.eclipse.che.api.workspace.server.WorkspaceService.class);
|
||||
install(new FactoryModuleBuilder().build(ServersCheckerFactory.class));
|
||||
|
|
@ -310,7 +303,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
bind(TokenValidator.class).to(org.eclipse.che.api.local.DummyTokenValidator.class);
|
||||
bind(MachineTokenProvider.class).to(MachineTokenProvider.EmptyMachineTokenProvider.class);
|
||||
|
||||
bind(org.eclipse.che.api.workspace.server.stack.StackLoader.class);
|
||||
bind(DataSource.class).toProvider(org.eclipse.che.core.db.h2.H2DataSourceProvider.class);
|
||||
|
||||
install(new org.eclipse.che.api.user.server.jpa.UserJpaModule());
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
<class>org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.VolumeImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.CommandImpl</class>
|
||||
|
||||
|
|
@ -68,8 +67,7 @@
|
|||
<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.workspace.server.stack.StackPermissionsImpl</class>
|
||||
|
||||
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl</class>
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl</class>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,160 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": "che-in-che",
|
||||
"creator": "ide",
|
||||
"name": "Eclipse Che",
|
||||
"description": "Utilities to build Che in Che with JDK 8 and Maven.",
|
||||
"scope": "general",
|
||||
"tags": [
|
||||
"Java",
|
||||
"JDK",
|
||||
"Maven",
|
||||
"Git",
|
||||
"SDK"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "JDK",
|
||||
"version": "1.8.0_92"
|
||||
},
|
||||
{
|
||||
"name": "Maven",
|
||||
"version": "3.3.9"
|
||||
}
|
||||
],
|
||||
"workspaceConfig": {
|
||||
"environments": {
|
||||
"default": {
|
||||
"machines": {
|
||||
"dev-machine": {
|
||||
"volumes": {
|
||||
"m2": {
|
||||
"path": "/home/user/.m2/"
|
||||
}
|
||||
},
|
||||
"installers": [
|
||||
"org.eclipse.che.exec",
|
||||
"org.eclipse.che.terminal",
|
||||
"org.eclipse.che.ws-agent",
|
||||
"org.eclipse.che.ls.js-ts",
|
||||
"org.eclipse.che.ls.java"
|
||||
],
|
||||
"servers": {
|
||||
"dev-wsagent/wsagent": {
|
||||
"path": "wsagent",
|
||||
"protocol": "ws",
|
||||
"port": "8087"
|
||||
},
|
||||
"GWT-CodeServer": {
|
||||
"protocol": "http",
|
||||
"port": "9876"
|
||||
},
|
||||
"IDE-agent-server": {
|
||||
"protocol": "http",
|
||||
"port": "8085"
|
||||
},
|
||||
"dev-wsagent/http": {
|
||||
"path": "api",
|
||||
"protocol": "http",
|
||||
"port": "8087"
|
||||
},
|
||||
"tomcat8" : {
|
||||
"port" : "8080",
|
||||
"protocol" : "http"
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"memoryLimitBytes": "7516192768"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recipe": {
|
||||
"content": "eclipse/che-dev:nightly",
|
||||
"type": "dockerimage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null,
|
||||
"commands": [
|
||||
{
|
||||
"commandLine": "cd ${current.project.path} && mvn clean install -Pnative",
|
||||
"name": "Build project",
|
||||
"type": "custom",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandLine": "cd ${current.project.eldest.parent.path} && mvn gwt:codeserver -pl :assembly-ide-war -am -Psdm-in-che -Dskip-enforce -Dskip-validate-sources -Dche.dto.skip -Dmaven.main.skip -Dmaven.resources.skip -Dmaven.buildNumber.skip",
|
||||
"name": "GWT SDM",
|
||||
"type": "gwt_sdm_che",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": "${server.GWT-CodeServer}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandLine": "cd /home/user/tomcat8/bin && export SERVER_PORT=8080 && export JPDA_ADDRESS=9000 && ./catalina.sh jpda run",
|
||||
"name": "Tomcat8-IDE Start",
|
||||
"type": "custom",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandLine": "cd /home/user/traefik && ./traefik",
|
||||
"name": "Traefik Start",
|
||||
"type": "custom",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandLine": "cd ${current.project.eldest.parent.path} && mvn clean install -pl :assembly-wsagent-war -am && cp ${current.project.eldest.parent.path}/assembly/assembly-wsagent-war/target/*.war /home/user/tomcat8/webapps/ROOT.war",
|
||||
"name": "Deploy Workspace Agent",
|
||||
"type": "custom",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": "${server.IDE-agent-server}/${workspace.namespace}/${workspace.name}?wsagent-ref-prefix=dev-"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandLine": "cd ${current.project.eldest.parent.path} && mvn clean install -pl :assembly-ide-war -am && cp ${current.project.eldest.parent.path}/assembly/assembly-ide-war/target/*.war /home/user/tomcat8/webapps/ide.war",
|
||||
"name": "Deploy IDE",
|
||||
"type": "custom",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": "${server.IDE-agent-server}/${workspace.namespace}/${workspace.name}?wsagent-ref-prefix=dev-"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandLine": "cp ${current.project.path}/target/*.jar /home/user/tomcat8/webapps/ROOT/WEB-INF/lib/ && echo \"Artifact copied. It takes a few seconds for Tomcat to hot deploy it.\"",
|
||||
"name": "Hot Deploy Workspace Agent",
|
||||
"type": "custom",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandLine": "cd ${current.project.eldest.parent.path} && mvn sortpom:sort fmt:format",
|
||||
"name": "Sort POM & Do Format",
|
||||
"type": "custom",
|
||||
"attributes": {
|
||||
"goal": "Run",
|
||||
"previewUrl": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"stackIcon": {
|
||||
"name": "type-che.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -352,15 +352,6 @@ db.schema.flyway.scripts.suffix=.sql
|
|||
db.schema.flyway.scripts.version_separator=__
|
||||
db.schema.flyway.scripts.locations=classpath:che-schema
|
||||
|
||||
# Defines whether stacks loaded once or each time server starts.
|
||||
# If value is 'false' stacks will be loaded once after database is initialized,
|
||||
# otherwise stacks will be loaded each time server starts.
|
||||
# Stacks loading overrides existing predefined stacks with new data
|
||||
# defined in stacks.json.
|
||||
# - 'default' : false
|
||||
# Note that this property is needed for backward compatibility and will be removed soon.
|
||||
che.predefined.stacks.reload_on_start=false
|
||||
|
||||
### Kubernetes Infra parameters
|
||||
|
||||
# Configuration of Kubernetes client that Infra will use
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ data:
|
|||
CHE_MULTIUSER: {{ .Values.global.multiuser | quote }}
|
||||
CHE_OAUTH_GITHUB_CLIENTID: {{ .Values.global.gitHubClientID | quote}}
|
||||
CHE_OAUTH_GITHUB_CLIENTSECRET: {{ .Values.global.gitHubClientSecret | quote}}
|
||||
CHE_PREDEFINED_STACKS_RELOAD__ON__START: "false"
|
||||
JAVA_OPTS: "-XX:MaxRAMFraction=2 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Dsun.zip.disableMemoryMapping=true -Xms20m "
|
||||
CHE_WORKSPACE_AUTO_START: "false"
|
||||
{{- if .Values.global.tls.enabled }}
|
||||
|
|
|
|||
|
|
@ -138,8 +138,6 @@ objects:
|
|||
value: "${CHE_OAUTH_GITHUB_CLIENTID}"
|
||||
- name: CHE_OAUTH_GITHUB_CLIENTSECRET
|
||||
value: "${CHE_OAUTH_GITHUB_CLIENTSECRET}"
|
||||
- name: CHE_PREDEFINED_STACKS_RELOAD__ON__START
|
||||
value: 'true'
|
||||
- name: JAVA_OPTS
|
||||
value: "-XX:MaxRAMFraction=2 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10
|
||||
-XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
*/
|
||||
package org.eclipse.che.multiuser.integration.jpa.cascaderemoval;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain.SET_PERMISSIONS;
|
||||
|
|
@ -22,7 +21,6 @@ import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjec
|
|||
import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjectsFactory.createProfile;
|
||||
import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjectsFactory.createSignatureKeyPair;
|
||||
import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjectsFactory.createSshPair;
|
||||
import static org.eclipse.che.multiuser.integration.jpa.cascaderemoval.TestObjectsFactory.createStack;
|
||||
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;
|
||||
|
|
@ -38,16 +36,13 @@ import static org.testng.Assert.fail;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Stage;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.multibindings.MapBinder;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import com.google.inject.name.Names;
|
||||
import com.google.inject.persist.jpa.JpaPersistModule;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Singleton;
|
||||
|
|
@ -81,9 +76,7 @@ import org.eclipse.che.api.workspace.server.WorkspaceSharedPool;
|
|||
import org.eclipse.che.api.workspace.server.WorkspaceStatusCache;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileModule;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
|
||||
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
|
||||
|
|
@ -100,8 +93,6 @@ import org.eclipse.che.inject.lifecycle.InitModule;
|
|||
import org.eclipse.che.multiuser.api.permission.server.PermissionChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionCheckerImpl;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
|
||||
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.machine.authentication.server.MachineAuthModule;
|
||||
import org.eclipse.che.multiuser.machine.authentication.server.signature.spi.SignatureKeyDao;
|
||||
import org.eclipse.che.multiuser.organization.api.OrganizationJpaModule;
|
||||
|
|
@ -113,11 +104,7 @@ 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.workspace.server.jpa.MultiuserWorkspaceJpaModule;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.jpa.listener.RemoveStackOnLastUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.WorkerDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaStackPermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.eclipse.che.multiuser.resource.api.AvailableResourcesProvider;
|
||||
import org.eclipse.che.multiuser.resource.api.ResourceLockKeyProvider;
|
||||
import org.eclipse.che.multiuser.resource.api.ResourceUsageTracker;
|
||||
|
|
@ -152,10 +139,8 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
private WorkspaceDao workspaceDao;
|
||||
private SshDao sshDao;
|
||||
private FactoryDao factoryDao;
|
||||
private StackDao stackDao;
|
||||
private WorkerDao workerDao;
|
||||
private SignatureKeyDao signatureKeyDao;
|
||||
private JpaStackPermissionsDao stackPermissionsDao;
|
||||
private FreeResourcesLimitDao freeResourcesLimitDao;
|
||||
private OrganizationManager organizationManager;
|
||||
private MemberDao memberDao;
|
||||
|
|
@ -196,12 +181,6 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
|
||||
private FactoryImpl factory2;
|
||||
|
||||
/** Stack depend on user via permissions */
|
||||
private StackImpl stack1;
|
||||
|
||||
private StackImpl stack2;
|
||||
private StackImpl stack3;
|
||||
|
||||
/** Organization depends on user via permissions */
|
||||
private Organization organization;
|
||||
|
||||
|
|
@ -314,7 +293,6 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
sshDao = injector.getInstance(SshDao.class);
|
||||
workspaceDao = injector.getInstance(WorkspaceDao.class);
|
||||
factoryDao = injector.getInstance(FactoryDao.class);
|
||||
stackDao = injector.getInstance(StackDao.class);
|
||||
workerDao = injector.getInstance(WorkerDao.class);
|
||||
signatureKeyDao = injector.getInstance(SignatureKeyDao.class);
|
||||
freeResourcesLimitDao = injector.getInstance(FreeResourcesLimitDao.class);
|
||||
|
|
@ -322,15 +300,6 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
memberDao = injector.getInstance(MemberDao.class);
|
||||
organizationResourcesDistributor = injector.getInstance(OrganizationResourcesDistributor.class);
|
||||
|
||||
TypeLiteral<Set<PermissionsDao<? extends AbstractPermissions>>> lit =
|
||||
new TypeLiteral<Set<PermissionsDao<? extends AbstractPermissions>>>() {};
|
||||
Key<Set<PermissionsDao<? extends AbstractPermissions>>> key = Key.get(lit);
|
||||
for (PermissionsDao<? extends AbstractPermissions> dao : injector.getInstance(key)) {
|
||||
if (dao.getDomain().getId().equals(StackDomain.DOMAIN_ID)) {
|
||||
stackPermissionsDao = (JpaStackPermissionsDao) dao;
|
||||
}
|
||||
}
|
||||
|
||||
h2JpaCleaner = injector.getInstance(H2JpaCleaner.class);
|
||||
}
|
||||
|
||||
|
|
@ -358,14 +327,8 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
// Check workers and parent entity is removed
|
||||
assertTrue(workspaceDao.getByNamespace(user2.getId(), 30, 0).isEmpty());
|
||||
assertEquals(workerDao.getWorkers(workspace3.getId(), 1, 0).getTotalItemsCount(), 0);
|
||||
// Check stack and recipes are removed
|
||||
assertNull(notFoundToNull(() -> stackDao.getById(stack1.getId())));
|
||||
assertNull(notFoundToNull(() -> stackDao.getById(stack2.getId())));
|
||||
// Permissions are removed
|
||||
assertTrue(stackPermissionsDao.getByUser(user2.getId()).isEmpty());
|
||||
// Non-removed user permissions and stack are present
|
||||
assertNotNull(notFoundToNull(() -> stackDao.getById(stack3.getId())));
|
||||
assertFalse(stackPermissionsDao.getByUser(user3.getId()).isEmpty());
|
||||
// Check existence of organizations
|
||||
assertNull(notFoundToNull(() -> organizationManager.getById(organization.getId())));
|
||||
assertEquals(memberDao.getMembers(organization.getId(), 1, 0).getTotalItemsCount(), 0);
|
||||
|
|
@ -391,7 +354,6 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
notFoundToNull(() -> organizationResourcesDistributor.get(childOrganization.getId())));
|
||||
|
||||
// cleanup
|
||||
stackDao.remove(stack3.getId());
|
||||
memberDao.remove(organization2.getId(), user3.getId());
|
||||
organizationManager.remove(organization2.getId());
|
||||
userDao.remove(user3.getId());
|
||||
|
|
@ -413,9 +375,6 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
|
||||
// Check all the data rolled back
|
||||
assertNotNull(userDao.getById(user2.getId()));
|
||||
assertFalse(stackPermissionsDao.getByUser(user2.getId()).isEmpty());
|
||||
assertNotNull(notFoundToNull(() -> stackDao.getById(stack1.getId())));
|
||||
assertNotNull(notFoundToNull(() -> stackDao.getById(stack2.getId())));
|
||||
assertNotNull(notFoundToNull(() -> freeResourcesLimitDao.get(account.getId())));
|
||||
assertNotNull(notFoundToNull(() -> organizationManager.getById(organization.getId())));
|
||||
assertNotNull(notFoundToNull(() -> organizationManager.getById(childOrganization.getId())));
|
||||
|
|
@ -429,7 +388,6 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
@DataProvider(name = "beforeRemoveRollbackActions")
|
||||
public Object[][] beforeRemoveActions() {
|
||||
return new Class[][] {
|
||||
{RemoveStackOnLastUserRemovedEventSubscriber.class, BeforeUserRemovedEvent.class},
|
||||
{RemoveOrganizationOnLastUserRemovedEventSubscriber.class, BeforeUserRemovedEvent.class}
|
||||
};
|
||||
}
|
||||
|
|
@ -456,29 +414,11 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
factoryDao.create(factory1 = createFactory("factory1", user.getId()));
|
||||
factoryDao.create(factory2 = createFactory("factory2", user.getId()));
|
||||
|
||||
stackDao.create(stack1 = createStack("stack1", "st1"));
|
||||
stackDao.create(stack2 = createStack("stack2", "st2"));
|
||||
stackDao.create(stack3 = createStack("stack3", "st3"));
|
||||
|
||||
workerDao.store(createWorker(user2.getId(), workspace3.getId()));
|
||||
|
||||
signatureKeyDao.create(createSignatureKeyPair(workspace1.getId()));
|
||||
signatureKeyDao.create(createSignatureKeyPair(workspace2.getId()));
|
||||
|
||||
stackPermissionsDao.store(
|
||||
new StackPermissionsImpl(
|
||||
user2.getId(), stack1.getId(), asList(SET_PERMISSIONS, "read", "write")));
|
||||
stackPermissionsDao.store(
|
||||
new StackPermissionsImpl(
|
||||
user2.getId(), stack2.getId(), asList(SET_PERMISSIONS, "read", "execute")));
|
||||
// To test removal only permissions if more users with setPermissions are present
|
||||
stackPermissionsDao.store(
|
||||
new StackPermissionsImpl(
|
||||
user2.getId(), stack3.getId(), asList(SET_PERMISSIONS, "read", "write")));
|
||||
stackPermissionsDao.store(
|
||||
new StackPermissionsImpl(
|
||||
user3.getId(), stack3.getId(), asList(SET_PERMISSIONS, "read", "write", "execute")));
|
||||
|
||||
// creator will have all permissions for newly created organization
|
||||
prepareCreator(user.getId());
|
||||
organization = organizationManager.create(new OrganizationImpl(null, "testOrg", null));
|
||||
|
|
@ -524,15 +464,6 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
organizationManager.remove(organization.getId());
|
||||
organizationManager.remove(organization2.getId());
|
||||
|
||||
stackPermissionsDao.remove(user2.getId(), stack1.getId());
|
||||
stackPermissionsDao.remove(user2.getId(), stack2.getId());
|
||||
stackPermissionsDao.remove(user2.getId(), stack3.getId());
|
||||
stackPermissionsDao.remove(user3.getId(), stack3.getId());
|
||||
|
||||
stackDao.remove(stack1.getId());
|
||||
stackDao.remove(stack2.getId());
|
||||
stackDao.remove(stack3.getId());
|
||||
|
||||
workerDao.removeWorker(workspace3.getId(), user2.getId());
|
||||
|
||||
factoryDao.remove(factory1.getId());
|
||||
|
|
|
|||
|
|
@ -29,9 +29,6 @@ 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.stack.StackComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
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;
|
||||
|
|
@ -96,24 +93,6 @@ public final class TestObjectsFactory {
|
|||
null);
|
||||
}
|
||||
|
||||
public static StackImpl createStack(String id, String name) {
|
||||
return StackImpl.builder()
|
||||
.setId(id)
|
||||
.setName(name)
|
||||
.setCreator("user123")
|
||||
.setDescription(id + "-description")
|
||||
.setScope(id + "-scope")
|
||||
.setWorkspaceConfig(createWorkspaceConfig(id + "test"))
|
||||
.setTags(asList(id + "-tag1", id + "-tag2"))
|
||||
.setComponents(
|
||||
asList(
|
||||
new StackComponentImpl(id + "-component1", id + "-component1-version"),
|
||||
new StackComponentImpl(id + "-component2", id + "-component2-version")))
|
||||
.setStackIcon(
|
||||
new StackIcon(id + "-icon", id + "-media-type", "0x1234567890abcdef".getBytes()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static WorkerImpl createWorker(String userId, String workspaceId) {
|
||||
return new WorkerImpl(workspaceId, userId, Arrays.asList("read", "write", "run"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
<class>org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.VolumeImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl</class>
|
||||
|
|
@ -64,7 +63,6 @@
|
|||
<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.workspace.server.stack.StackPermissionsImpl</class>
|
||||
<class>org.eclipse.che.api.ssh.server.model.impl.SshPairImpl</class>
|
||||
|
||||
<class>org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl</class>
|
||||
|
|
|
|||
|
|
@ -252,11 +252,7 @@
|
|||
<port>jdbc.port:3306</port>
|
||||
</ports>
|
||||
<wait>
|
||||
<tcp>
|
||||
<ports>
|
||||
<port>3306</port>
|
||||
</ports>
|
||||
</tcp>
|
||||
<log>ready for connections</log>
|
||||
<time>60000</time>
|
||||
</wait>
|
||||
<restartPolicy>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ import javax.persistence.spi.PersistenceUnitTransactionType;
|
|||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.commons.test.tck.JpaCleaner;
|
||||
import org.eclipse.che.commons.test.tck.TckModule;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
|
|
@ -71,11 +70,8 @@ import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDao;
|
|||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDistributedResourcesDao;
|
||||
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.JpaStackPermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaWorkerDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.tck.StackPermissionsDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.tck.WorkerDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.eclipse.che.multiuser.resource.spi.FreeResourcesLimitDao;
|
||||
import org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl;
|
||||
import org.eclipse.che.multiuser.resource.spi.jpa.JpaFreeResourcesLimitDao;
|
||||
|
|
@ -132,24 +128,16 @@ public class MultiuserMySqlTckModule extends TckModule {
|
|||
// api-workspace
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(WorkspaceImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<StackImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(StackImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<WorkerImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(WorkerImpl.class));
|
||||
|
||||
// api permission
|
||||
bind(new TypeLiteral<TckRepository<StackPermissionsImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(StackPermissionsImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<SystemPermissionsImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(SystemPermissionsImpl.class));
|
||||
|
||||
bind(new TypeLiteral<PermissionsDao<StackPermissionsImpl>>() {})
|
||||
.to(JpaStackPermissionsDao.class);
|
||||
bind(new TypeLiteral<PermissionsDao<SystemPermissionsImpl>>() {})
|
||||
.to(JpaSystemPermissionsDao.class);
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<StackPermissionsImpl>>() {})
|
||||
.to(StackPermissionsDaoTest.TestDomain.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<WorkerImpl>>() {})
|
||||
.to(WorkerDaoTest.TestDomain.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<SystemPermissionsImpl>>() {})
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
<class>org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.VolumeImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl</class>
|
||||
|
|
@ -57,7 +56,6 @@
|
|||
<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.workspace.server.stack.StackPermissionsImpl</class>
|
||||
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl</class>
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl</class>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ import javax.persistence.spi.PersistenceUnitTransactionType;
|
|||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.commons.test.tck.JpaCleaner;
|
||||
import org.eclipse.che.commons.test.tck.TckModule;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
|
|
@ -71,11 +70,8 @@ import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDao;
|
|||
import org.eclipse.che.multiuser.organization.spi.jpa.JpaOrganizationDistributedResourcesDao;
|
||||
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.JpaStackPermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaWorkerDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.tck.StackPermissionsDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.tck.WorkerDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.eclipse.che.multiuser.resource.spi.FreeResourcesLimitDao;
|
||||
import org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl;
|
||||
import org.eclipse.che.multiuser.resource.spi.jpa.JpaFreeResourcesLimitDao;
|
||||
|
|
@ -131,24 +127,16 @@ public class MultiuserPostgresqlTckModule extends TckModule {
|
|||
// api-workspace
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(WorkspaceImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<StackImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(StackImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<WorkerImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(WorkerImpl.class));
|
||||
|
||||
// api permission
|
||||
bind(new TypeLiteral<TckRepository<StackPermissionsImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(StackPermissionsImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<SystemPermissionsImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(SystemPermissionsImpl.class));
|
||||
|
||||
bind(new TypeLiteral<PermissionsDao<StackPermissionsImpl>>() {})
|
||||
.to(JpaStackPermissionsDao.class);
|
||||
bind(new TypeLiteral<PermissionsDao<SystemPermissionsImpl>>() {})
|
||||
.to(JpaSystemPermissionsDao.class);
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<StackPermissionsImpl>>() {})
|
||||
.to(StackPermissionsDaoTest.TestDomain.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<WorkerImpl>>() {})
|
||||
.to(WorkerDaoTest.TestDomain.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<SystemPermissionsImpl>>() {})
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
<class>org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.VolumeImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl</class>
|
||||
|
|
@ -57,7 +56,6 @@
|
|||
<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.workspace.server.stack.StackPermissionsImpl</class>
|
||||
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl</class>
|
||||
<class>org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl</class>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ 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.stack.StackImpl;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
import org.eclipse.che.commons.test.db.PersistTestModuleBuilder;
|
||||
|
|
@ -73,7 +72,6 @@ public class SignatureKeyTckModule extends TckModule {
|
|||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
StackImpl.class,
|
||||
CommandImpl.class,
|
||||
RecipeImpl.class,
|
||||
VolumeImpl.class,
|
||||
|
|
|
|||
|
|
@ -12,23 +12,13 @@
|
|||
package org.eclipse.che.multiuser.permission.workspace.server;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.multibindings.MapBinder;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import com.google.inject.name.Names;
|
||||
import org.eclipse.che.api.workspace.server.stack.StackLoader;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.RemovePermissionsChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.SetPermissionsChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.model.PermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.filters.InstallerServicePermissionFilter;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.filters.PublicPermissionsRemoveChecker;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.filters.StackDomainSetPermissionsChecker;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.filters.StackPermissionsFilter;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.filters.WorkspacePermissionsFilter;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.filters.WorkspaceRemoteSubscriptionPermissionFilter;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.MultiuserStackLoader;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackCreatorPermissionsProvider;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain;
|
||||
|
||||
/** @author Sergii Leschenko */
|
||||
public class WorkspaceApiPermissionsModule extends AbstractModule {
|
||||
|
|
@ -36,13 +26,10 @@ public class WorkspaceApiPermissionsModule extends AbstractModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
bind(WorkspacePermissionsFilter.class);
|
||||
bind(StackPermissionsFilter.class);
|
||||
bind(InstallerServicePermissionFilter.class).asEagerSingleton();
|
||||
bind(WorkspaceRemoteSubscriptionPermissionFilter.class).asEagerSingleton();
|
||||
|
||||
bind(WorkspaceCreatorPermissionsProvider.class).asEagerSingleton();
|
||||
bind(StackCreatorPermissionsProvider.class).asEagerSingleton();
|
||||
bind(StackLoader.class).to(MultiuserStackLoader.class);
|
||||
|
||||
Multibinder.newSetBinder(
|
||||
binder(),
|
||||
|
|
@ -50,13 +37,5 @@ public class WorkspaceApiPermissionsModule extends AbstractModule {
|
|||
Names.named(SuperPrivilegesChecker.SUPER_PRIVILEGED_DOMAINS))
|
||||
.addBinding()
|
||||
.to(WorkspaceDomain.class);
|
||||
|
||||
MapBinder.newMapBinder(binder(), String.class, SetPermissionsChecker.class)
|
||||
.addBinding(StackDomain.DOMAIN_ID)
|
||||
.to(StackDomainSetPermissionsChecker.class);
|
||||
|
||||
MapBinder.newMapBinder(binder(), String.class, RemovePermissionsChecker.class)
|
||||
.addBinding(StackDomain.DOMAIN_ID)
|
||||
.to(PublicPermissionsRemoveChecker.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +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.workspace.server.filters;
|
||||
|
||||
import static org.eclipse.che.multiuser.api.permission.server.SystemDomain.DOMAIN_ID;
|
||||
import static org.eclipse.che.multiuser.api.permission.server.SystemDomain.MANAGE_SYSTEM_ACTION;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.ApiException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.DefaultRemovePermissionsChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.RemovePermissionsChecker;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain;
|
||||
|
||||
/**
|
||||
* Recipe and Stack domains remove permissions checker.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Singleton
|
||||
public class PublicPermissionsRemoveChecker implements RemovePermissionsChecker {
|
||||
|
||||
private final DefaultRemovePermissionsChecker defaultChecker;
|
||||
private final PermissionsManager permissionsManager;
|
||||
|
||||
@Inject
|
||||
public PublicPermissionsRemoveChecker(
|
||||
DefaultRemovePermissionsChecker defaultChecker, PermissionsManager permissionsManager) {
|
||||
this.defaultChecker = defaultChecker;
|
||||
this.permissionsManager = permissionsManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(String user, String domain, String instance) throws ForbiddenException {
|
||||
if (!"*".equals(user)
|
||||
|| !EnvironmentContext.getCurrent()
|
||||
.getSubject()
|
||||
.hasPermission(DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)) {
|
||||
defaultChecker.check(user, domain, instance);
|
||||
return;
|
||||
}
|
||||
final Set<String> actions = new HashSet<>();
|
||||
try {
|
||||
actions.addAll(permissionsManager.get(user, domain, instance).getActions());
|
||||
} catch (ApiException ignored) {
|
||||
}
|
||||
|
||||
// perform default check if no search action found or its not admin user
|
||||
if (!actions.contains(StackDomain.SEARCH)) {
|
||||
defaultChecker.check(user, domain, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +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.workspace.server.filters;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.multiuser.api.permission.server.SystemDomain.MANAGE_SYSTEM_ACTION;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.SEARCH;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.getActions;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SystemDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.DefaultSetPermissionsChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.SetPermissionsChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.model.Permissions;
|
||||
|
||||
/**
|
||||
* Stack domain specific set permission checker.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Singleton
|
||||
public class StackDomainSetPermissionsChecker implements SetPermissionsChecker {
|
||||
|
||||
private final DefaultSetPermissionsChecker defaultChecker;
|
||||
|
||||
@Inject
|
||||
public StackDomainSetPermissionsChecker(DefaultSetPermissionsChecker defaultChecker) {
|
||||
this.defaultChecker = defaultChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(Permissions permissions) throws ForbiddenException {
|
||||
if (!"*".equals(permissions.getUserId())) {
|
||||
defaultChecker.check(permissions);
|
||||
return;
|
||||
}
|
||||
final Set<String> unsupportedPublicActions = new HashSet<>(permissions.getActions());
|
||||
unsupportedPublicActions.remove(READ);
|
||||
|
||||
// public search is supported only for admins
|
||||
if (EnvironmentContext.getCurrent()
|
||||
.getSubject()
|
||||
.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)) {
|
||||
unsupportedPublicActions.remove(SEARCH);
|
||||
} else {
|
||||
defaultChecker.check(permissions);
|
||||
}
|
||||
|
||||
if (!unsupportedPublicActions.isEmpty()) {
|
||||
throw new ForbiddenException(
|
||||
"Following actions are not supported for setting as public:"
|
||||
+ getActions()
|
||||
.stream()
|
||||
.filter(a -> !(a.equals(READ) || a.equals(SEARCH)))
|
||||
.collect(toList()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,162 +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.workspace.server.filters;
|
||||
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.DOMAIN_ID;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.SEARCH;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.UPDATE;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.Inject;
|
||||
import javax.ws.rs.Path;
|
||||
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.workspace.server.stack.StackService;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.everrest.CheMethodInvokerFilter;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SystemDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.resource.GenericResourceMethod;
|
||||
|
||||
/**
|
||||
* Restricts access to methods of {@link StackService} by users' permissions
|
||||
*
|
||||
* <p>Filter should contain rules for protecting of all methods of {@link StackService}.<br>
|
||||
* In case when requested method is unknown filter throws {@link ForbiddenException}
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
* @author Mykola Morhun
|
||||
*/
|
||||
@Filter
|
||||
@Path("/stack{path:(/.*)?}")
|
||||
public class StackPermissionsFilter extends CheMethodInvokerFilter {
|
||||
|
||||
private final PermissionsManager permissionsManager;
|
||||
|
||||
@Inject
|
||||
public StackPermissionsFilter(PermissionsManager permissionsManager) {
|
||||
this.permissionsManager = permissionsManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(GenericResourceMethod genericResourceMethod, Object[] arguments)
|
||||
throws ForbiddenException, ServerException {
|
||||
final String methodName = genericResourceMethod.getMethod().getName();
|
||||
|
||||
final Subject currentSubject = EnvironmentContext.getCurrent().getSubject();
|
||||
String action;
|
||||
String stackId;
|
||||
|
||||
switch (methodName) {
|
||||
case "getStack":
|
||||
case "getIcon":
|
||||
stackId = ((String) arguments[0]);
|
||||
action = READ;
|
||||
|
||||
if (currentSubject.hasPermission(DOMAIN_ID, stackId, SEARCH)) {
|
||||
// allow to read stack if user has 'search' permission
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case "updateStack":
|
||||
case "uploadIcon":
|
||||
stackId = ((String) arguments[1]);
|
||||
action = UPDATE;
|
||||
break;
|
||||
|
||||
case "removeIcon":
|
||||
stackId = ((String) arguments[0]);
|
||||
action = UPDATE;
|
||||
break;
|
||||
|
||||
case "removeStack":
|
||||
stackId = ((String) arguments[0]);
|
||||
action = DELETE;
|
||||
break;
|
||||
|
||||
case "createStack":
|
||||
case "searchStacks":
|
||||
// available for all
|
||||
return;
|
||||
default:
|
||||
throw new ForbiddenException("The user does not have permission to perform this operation");
|
||||
}
|
||||
|
||||
if (currentSubject.hasPermission(
|
||||
SystemDomain.DOMAIN_ID, null, SystemDomain.MANAGE_SYSTEM_ACTION)
|
||||
&& isStackPredefined(stackId)) {
|
||||
// allow any operation with predefined stack if user has 'manageSystem' permission
|
||||
return;
|
||||
}
|
||||
|
||||
if (!currentSubject.hasPermission(DOMAIN_ID, stackId, action)) {
|
||||
throw new ForbiddenException(
|
||||
"The user does not have permission to " + action + " stack with id '" + stackId + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether stack is predefined. Note, that 'predefined' means public for all users (not
|
||||
* necessary provided with system from the box).
|
||||
*
|
||||
* @param stackId id of stack to test
|
||||
* @return true if stack is predefined, false otherwise
|
||||
* @throws ServerException when any error occurs during permissions fetching
|
||||
*/
|
||||
@VisibleForTesting
|
||||
boolean isStackPredefined(String stackId) throws ServerException {
|
||||
try {
|
||||
Page<AbstractPermissions> permissionsPage =
|
||||
permissionsManager.getByInstance(DOMAIN_ID, stackId, 25, 0);
|
||||
do {
|
||||
for (AbstractPermissions stackPermission : permissionsPage.getItems()) {
|
||||
if ("*".equals(stackPermission.getUserId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while ((permissionsPage = getNextPermissionsPage(stackId, permissionsPage)) != null);
|
||||
} catch (NotFoundException e) {
|
||||
// should never happen
|
||||
throw new ServerException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves next permissions page for given stack.
|
||||
*
|
||||
* @param stackId id of stack to which permissions will be obtained
|
||||
* @param permissionsPage previous permissions page
|
||||
* @return next permissions page for given stack or null if next page doesn't exist
|
||||
* @throws ServerException when any error occurs during permissions fetching
|
||||
*/
|
||||
@VisibleForTesting
|
||||
Page<AbstractPermissions> getNextPermissionsPage(
|
||||
String stackId, Page<AbstractPermissions> permissionsPage)
|
||||
throws NotFoundException, ServerException {
|
||||
if (!permissionsPage.hasNextPage()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Page.PageRef nextPageRef = permissionsPage.getNextPageRef();
|
||||
return permissionsManager.getByInstance(
|
||||
DOMAIN_ID, stackId, nextPageRef.getPageSize(), nextPageRef.getItemsBefore());
|
||||
}
|
||||
}
|
||||
|
|
@ -15,29 +15,21 @@ import com.google.inject.AbstractModule;
|
|||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao.RemoveWorkspaceBeforeAccountRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.jpa.listener.RemovePermissionsOnLastUserRemovedEventSubscriber;
|
||||
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.workspace.server.WorkspaceDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.jpa.listener.RemoveStackOnLastUserRemovedEventSubscriber;
|
||||
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.JpaStackPermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaWorkerDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.MultiuserJpaStackDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.MultiuserJpaWorkspaceDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
|
||||
/** @author Yevhenii Voevodin */
|
||||
public class MultiuserWorkspaceJpaModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(StackDao.class).to(MultiuserJpaStackDao.class);
|
||||
bind(WorkerDao.class).to(JpaWorkerDao.class);
|
||||
bind(WorkspaceDao.class).to(MultiuserJpaWorkspaceDao.class);
|
||||
bind(RemoveWorkspaceBeforeAccountRemovedEventSubscriber.class).asEagerSingleton();
|
||||
|
|
@ -45,20 +37,11 @@ public class MultiuserWorkspaceJpaModule extends AbstractModule {
|
|||
bind(JpaWorkerDao.RemoveWorkersBeforeWorkspaceRemovedEventSubscriber.class).asEagerSingleton();
|
||||
bind(JpaWorkerDao.RemoveWorkersBeforeUserRemovedEventSubscriber.class).asEagerSingleton();
|
||||
|
||||
bind(new TypeLiteral<
|
||||
RemovePermissionsOnLastUserRemovedEventSubscriber<JpaStackPermissionsDao>>() {})
|
||||
.to(RemoveStackOnLastUserRemovedEventSubscriber.class);
|
||||
bind(JpaStackPermissionsDao.RemovePermissionsBeforeStackRemovedEventSubscriber.class)
|
||||
.asEagerSingleton();
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<StackPermissionsImpl>>() {})
|
||||
.to(StackDomain.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<WorkerImpl>>() {}).to(WorkspaceDomain.class);
|
||||
|
||||
Multibinder<PermissionsDao<? extends AbstractPermissions>> daos =
|
||||
Multibinder.newSetBinder(
|
||||
binder(), new TypeLiteral<PermissionsDao<? extends AbstractPermissions>>() {});
|
||||
daos.addBinding().to(JpaWorkerDao.class);
|
||||
daos.addBinding().to(JpaStackPermissionsDao.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +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.workspace.server.jpa.listener;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaStackDao;
|
||||
import org.eclipse.che.multiuser.api.permission.server.jpa.listener.RemovePermissionsOnLastUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaStackPermissionsDao;
|
||||
|
||||
/**
|
||||
* Listens for {@link UserImpl} removal events, and checks if the removing user is the last who have
|
||||
* "setPermissions" role to particular stack, and if it is, then removes stack itself.
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
@Singleton
|
||||
public class RemoveStackOnLastUserRemovedEventSubscriber
|
||||
extends RemovePermissionsOnLastUserRemovedEventSubscriber<JpaStackPermissionsDao> {
|
||||
|
||||
@Inject private JpaStackDao stackDao;
|
||||
|
||||
@Override
|
||||
public void remove(String instanceId) throws ServerException {
|
||||
stackDao.remove(instanceId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,186 +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.workspace.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.workspace.server.event.BeforeStackRemovedEvent;
|
||||
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.workspace.server.stack.StackPermissionsImpl;
|
||||
|
||||
/**
|
||||
* JPA based implementation of stack permissions DAO.
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
@Singleton
|
||||
public class JpaStackPermissionsDao extends AbstractJpaPermissionsDao<StackPermissionsImpl> {
|
||||
|
||||
@Inject
|
||||
public JpaStackPermissionsDao(AbstractPermissionsDomain<StackPermissionsImpl> domain) {
|
||||
super(domain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackPermissionsImpl get(String userId, String instanceId)
|
||||
throws ServerException, NotFoundException {
|
||||
requireNonNull(instanceId, "Stack identifier required");
|
||||
requireNonNull(userId, "User identifier required");
|
||||
try {
|
||||
return new StackPermissionsImpl(getEntity(wildcardToNull(userId), instanceId));
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StackPermissionsImpl> getByUser(String userId) throws ServerException {
|
||||
requireNonNull(userId, "User identifier required");
|
||||
return doGetByUser(wildcardToNull(userId))
|
||||
.stream()
|
||||
.map(StackPermissionsImpl::new)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Page<StackPermissionsImpl> getByInstance(String instanceId, int maxItems, long skipCount)
|
||||
throws ServerException {
|
||||
requireNonNull(instanceId, "Stack 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<StackPermissionsImpl> stacks =
|
||||
entityManager
|
||||
.createNamedQuery("StackPermissions.getByStackId", StackPermissionsImpl.class)
|
||||
.setFirstResult((int) skipCount)
|
||||
.setMaxResults(maxItems)
|
||||
.setParameter("stackId", instanceId)
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(StackPermissionsImpl::new)
|
||||
.collect(toList());
|
||||
final Long permissionsCount =
|
||||
entityManager
|
||||
.createNamedQuery("StackPermissions.getCountByStackId", Long.class)
|
||||
.setParameter("stackId", instanceId)
|
||||
.getSingleResult();
|
||||
|
||||
return new Page<>(stacks, skipCount, maxItems, permissionsCount);
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackPermissionsImpl getEntity(String userId, String instanceId)
|
||||
throws NotFoundException, ServerException {
|
||||
try {
|
||||
return doGet(userId, instanceId);
|
||||
} catch (NoResultException e) {
|
||||
throw new NotFoundException(
|
||||
format("Permissions on stack '%s' of user '%s' was not found.", instanceId, userId));
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServerException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected StackPermissionsImpl doGet(String userId, String instanceId) {
|
||||
if (userId == null) {
|
||||
return managerProvider
|
||||
.get()
|
||||
.createNamedQuery("StackPermissions.getByStackIdPublic", StackPermissionsImpl.class)
|
||||
.setParameter("stackId", instanceId)
|
||||
.getSingleResult();
|
||||
} else {
|
||||
return managerProvider
|
||||
.get()
|
||||
.createNamedQuery("StackPermissions.getByUserAndStackId", StackPermissionsImpl.class)
|
||||
.setParameter("stackId", instanceId)
|
||||
.setParameter("userId", userId)
|
||||
.getSingleResult();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected List<StackPermissionsImpl> doGetByUser(@Nullable String userId) throws ServerException {
|
||||
try {
|
||||
return managerProvider
|
||||
.get()
|
||||
.createNamedQuery("StackPermissions.getByUserId", StackPermissionsImpl.class)
|
||||
.setParameter("userId", userId)
|
||||
.getResultList();
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class RemovePermissionsBeforeStackRemovedEventSubscriber
|
||||
extends CascadeEventSubscriber<BeforeStackRemovedEvent> {
|
||||
private static final int PAGE_SIZE = 100;
|
||||
@Inject private EventService eventService;
|
||||
@Inject private JpaStackPermissionsDao dao;
|
||||
|
||||
@PostConstruct
|
||||
public void subscribe() {
|
||||
eventService.subscribe(this, BeforeStackRemovedEvent.class);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void unsubscribe() {
|
||||
eventService.unsubscribe(this, BeforeStackRemovedEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCascadeEvent(BeforeStackRemovedEvent event) throws Exception {
|
||||
removeStackPermissions(event.getStack().getId(), PAGE_SIZE);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void removeStackPermissions(String stackId, int pageSize)
|
||||
throws ServerException, NotFoundException {
|
||||
Page<StackPermissionsImpl> stacksPage;
|
||||
do {
|
||||
// skip count always equals to 0 because elements will be shifted after removing previous
|
||||
// items
|
||||
stacksPage = dao.getByInstance(stackId, pageSize, 0);
|
||||
for (StackPermissionsImpl stackPermissions : stacksPage.getItems()) {
|
||||
dao.remove(stackPermissions.getUserId(), stackPermissions.getInstanceId());
|
||||
}
|
||||
} while (stacksPage.hasNextPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,182 +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.workspace.server.spi.jpa;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
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.api.core.ApiException;
|
||||
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.workspace.server.event.BeforeStackRemovedEvent;
|
||||
import org.eclipse.che.api.workspace.server.event.StackPersistedEvent;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
|
||||
|
||||
/**
|
||||
* JPA based implementation of {@link StackDao}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class MultiuserJpaStackDao implements StackDao {
|
||||
|
||||
@Inject private Provider<EntityManager> managerProvider;
|
||||
|
||||
@Inject private EventService eventService;
|
||||
|
||||
private static final String findByPermissionsQuery =
|
||||
" SELECT stack FROM StackPermissions perm "
|
||||
+ " LEFT JOIN perm.stack stack "
|
||||
+ " WHERE (perm.userId IS NULL OR perm.userId = :userId) "
|
||||
+ " AND 'search' MEMBER OF perm.actions"
|
||||
+ " GROUP BY stack.id";
|
||||
|
||||
private static final String findByPermissionsAndTagsQuery =
|
||||
" SELECT stack FROM StackPermissions perm "
|
||||
+ " LEFT JOIN perm.stack stack "
|
||||
+ " LEFT JOIN stack.tags tag "
|
||||
+ " WHERE (perm.userId IS NULL OR perm.userId = :userId) "
|
||||
+ " AND 'search' MEMBER OF perm.actions"
|
||||
+ " AND tag IN :tags "
|
||||
+ " GROUP BY stack.id HAVING COUNT(tag) = :tagsSize";
|
||||
|
||||
@Override
|
||||
public void create(StackImpl stack) throws ConflictException, ServerException {
|
||||
requireNonNull(stack, "Required non-null stack");
|
||||
try {
|
||||
doCreate(stack);
|
||||
} catch (DuplicateKeyException x) {
|
||||
throw new ConflictException(
|
||||
format("Stack with id '%s' or name '%s' already exists", stack.getId(), stack.getName()));
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public StackImpl getById(String id) throws NotFoundException, ServerException {
|
||||
requireNonNull(id, "Required non-null id");
|
||||
try {
|
||||
final StackImpl stack = managerProvider.get().find(StackImpl.class, id);
|
||||
if (stack == null) {
|
||||
throw new NotFoundException(format("Stack with id '%s' doesn't exist", id));
|
||||
}
|
||||
return new StackImpl(stack);
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String id) throws ServerException {
|
||||
requireNonNull(id, "Required non-null id");
|
||||
try {
|
||||
doRemove(id);
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackImpl update(StackImpl update)
|
||||
throws NotFoundException, ServerException, ConflictException {
|
||||
requireNonNull(update, "Required non-null update");
|
||||
try {
|
||||
return new StackImpl(doUpdate(update));
|
||||
} catch (DuplicateKeyException x) {
|
||||
throw new ConflictException(format("Stack with name '%s' already exists", update.getName()));
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<StackImpl> searchStacks(
|
||||
@Nullable String userId, @Nullable List<String> tags, int skipCount, int maxItems)
|
||||
throws ServerException {
|
||||
final TypedQuery<StackImpl> query;
|
||||
if (tags == null || tags.isEmpty()) {
|
||||
query = managerProvider.get().createQuery(findByPermissionsQuery, StackImpl.class);
|
||||
} else {
|
||||
query =
|
||||
managerProvider
|
||||
.get()
|
||||
.createQuery(findByPermissionsAndTagsQuery, StackImpl.class)
|
||||
.setParameter("tags", tags)
|
||||
.setParameter("tagsSize", tags.size());
|
||||
}
|
||||
try {
|
||||
return query
|
||||
.setParameter("userId", userId)
|
||||
.setMaxResults(maxItems)
|
||||
.setFirstResult(skipCount)
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(StackImpl::new)
|
||||
.collect(Collectors.toList());
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {RuntimeException.class, ApiException.class})
|
||||
protected void doCreate(StackImpl stack) throws ConflictException, ServerException {
|
||||
if (stack.getWorkspaceConfig() != null) {
|
||||
stack.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
EntityManager manager = managerProvider.get();
|
||||
manager.persist(stack);
|
||||
manager.flush();
|
||||
eventService.publish(new StackPersistedEvent(stack)).propagateException();
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {RuntimeException.class, ServerException.class})
|
||||
protected void doRemove(String id) throws ServerException {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
final StackImpl stack = manager.find(StackImpl.class, id);
|
||||
if (stack != null) {
|
||||
eventService.publish(new BeforeStackRemovedEvent(new StackImpl(stack))).propagateException();
|
||||
manager.remove(stack);
|
||||
manager.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected StackImpl doUpdate(StackImpl update) throws NotFoundException {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
if (manager.find(StackImpl.class, update.getId()) == null) {
|
||||
throw new NotFoundException(format("Workspace with id '%s' doesn't exist", update.getId()));
|
||||
}
|
||||
if (update.getWorkspaceConfig() != null) {
|
||||
update.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
StackImpl merged = manager.merge(update);
|
||||
manager.flush();
|
||||
return merged;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +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.workspace.server.stack;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
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.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.stack.StackLoader;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
import org.eclipse.che.core.db.DBInitializer;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaStackPermissionsDao;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Class for loading list predefined {@link Stack} to the {@link StackDao} and set {@link StackIcon}
|
||||
* to the predefined stack.
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
* @author Sergii Leshchenko
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Singleton
|
||||
public class MultiuserStackLoader extends StackLoader {
|
||||
|
||||
public static final String CHE_PREDEFINED_STACKS = "che.predefined.stacks";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MultiuserStackLoader.class);
|
||||
|
||||
private final JpaStackPermissionsDao permissionsDao;
|
||||
|
||||
@Inject
|
||||
@SuppressWarnings("unused")
|
||||
public MultiuserStackLoader(
|
||||
@Named("che.predefined.stacks.reload_on_start") boolean reloadStacksOnStart,
|
||||
@Named(CHE_PREDEFINED_STACKS) Map<String, String> stacks2images,
|
||||
StackDao stackDao,
|
||||
JpaStackPermissionsDao permissionsDao,
|
||||
DBInitializer dbInitializer) {
|
||||
super(reloadStacksOnStart, stacks2images, stackDao, dbInitializer);
|
||||
this.permissionsDao = permissionsDao;
|
||||
}
|
||||
|
||||
protected void loadStack(StackImpl stack, Path imagePath) {
|
||||
setIconData(stack, imagePath);
|
||||
try {
|
||||
try {
|
||||
stackDao.update(stack);
|
||||
} catch (NotFoundException ignored) {
|
||||
stackDao.create(stack);
|
||||
}
|
||||
permissionsDao.store(
|
||||
new StackPermissionsImpl("*", stack.getId(), singletonList(StackDomain.SEARCH)));
|
||||
} catch (ServerException | ConflictException ex) {
|
||||
LOG.warn(format("Failed to load stack with id '%s' ", stack.getId()), ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +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.workspace.server.stack;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.workspace.server.event.StackPersistedEvent;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.core.db.cascade.CascadeEventSubscriber;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
|
||||
|
||||
/**
|
||||
* Grants access to stack which is created by user who is {@link EnvironmentContext#getSubject()
|
||||
* subject}, if there is no subject present in {@link EnvironmentContext#getCurrent() current}
|
||||
* context then no permissions will be added.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class StackCreatorPermissionsProvider extends CascadeEventSubscriber<StackPersistedEvent> {
|
||||
|
||||
@Inject private PermissionsManager permissionsManager;
|
||||
|
||||
@Inject private EventService eventService;
|
||||
|
||||
@Override
|
||||
public void onCascadeEvent(StackPersistedEvent event) throws Exception {
|
||||
final Subject subject = EnvironmentContext.getCurrent().getSubject();
|
||||
if (!subject.isAnonymous()) {
|
||||
permissionsManager.storePermission(
|
||||
new StackPermissionsImpl(
|
||||
subject.getUserId(), event.getStack().getId(), StackDomain.getActions()));
|
||||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void subscribe() {
|
||||
eventService.subscribe(this, StackPersistedEvent.class);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void unsubscribe() {
|
||||
eventService.unsubscribe(this, StackPersistedEvent.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.workspace.server.stack;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
|
||||
/**
|
||||
* Domain for storing stacks' permissions
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class StackDomain extends AbstractPermissionsDomain<StackPermissionsImpl> {
|
||||
public static final String DOMAIN_ID = "stack";
|
||||
|
||||
public static final String READ = "read";
|
||||
public static final String SEARCH = "search";
|
||||
public static final String UPDATE = "update";
|
||||
public static final String DELETE = "delete";
|
||||
|
||||
private static final List<String> ACTIONS =
|
||||
ImmutableList.of(SET_PERMISSIONS, READ, SEARCH, UPDATE, DELETE);
|
||||
|
||||
/** Returns all the available actions for {@link StackDomain}. */
|
||||
public static List<String> getActions() {
|
||||
return ACTIONS;
|
||||
}
|
||||
|
||||
public StackDomain() {
|
||||
super(DOMAIN_ID, ACTIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackPermissionsImpl doCreateInstance(
|
||||
String userId, String instanceId, List<String> allowedActions) {
|
||||
return new StackPermissionsImpl(userId, instanceId, allowedActions);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +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.workspace.server.stack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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.Table;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.model.Permissions;
|
||||
|
||||
/**
|
||||
* Stack permissions data object.
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
@Entity(name = "StackPermissions")
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "StackPermissions.getByStackId",
|
||||
query = "SELECT stack " + "FROM StackPermissions stack " + "WHERE stack.stackId = :stackId "),
|
||||
@NamedQuery(
|
||||
name = "StackPermissions.getCountByStackId",
|
||||
query =
|
||||
"SELECT COUNT(stack) "
|
||||
+ "FROM StackPermissions stack "
|
||||
+ "WHERE stack.stackId = :stackId "),
|
||||
@NamedQuery(
|
||||
name = "StackPermissions.getByUserId",
|
||||
query = "SELECT stack " + "FROM StackPermissions stack " + "WHERE stack.userId = :userId "),
|
||||
@NamedQuery(
|
||||
name = "StackPermissions.getByUserAndStackId",
|
||||
query =
|
||||
"SELECT stack "
|
||||
+ "FROM StackPermissions stack "
|
||||
+ "WHERE stack.stackId = :stackId "
|
||||
+ "AND stack.userId = :userId "),
|
||||
@NamedQuery(
|
||||
name = "StackPermissions.getByStackIdPublic",
|
||||
query =
|
||||
"SELECT stack "
|
||||
+ "FROM StackPermissions stack "
|
||||
+ "WHERE stack.stackId = :stackId "
|
||||
+ "AND stack.userId IS NULL ")
|
||||
})
|
||||
@Table(name = "che_stack_permissions")
|
||||
public class StackPermissionsImpl extends AbstractPermissions {
|
||||
|
||||
@Column(name = "stack_id")
|
||||
private String stackId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "stack_id", insertable = false, updatable = false)
|
||||
private StackImpl stack;
|
||||
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@Column(name = "actions")
|
||||
@CollectionTable(
|
||||
name = "che_stack_permissions_actions",
|
||||
joinColumns = @JoinColumn(name = "stack_permissions_id"))
|
||||
protected List<String> actions;
|
||||
|
||||
public StackPermissionsImpl() {}
|
||||
|
||||
public StackPermissionsImpl(Permissions permissions) {
|
||||
this(permissions.getUserId(), permissions.getInstanceId(), permissions.getActions());
|
||||
}
|
||||
|
||||
public StackPermissionsImpl(String userId, String instanceId, List<String> allowedActions) {
|
||||
super(userId);
|
||||
this.stackId = instanceId;
|
||||
if (allowedActions != null) {
|
||||
this.actions = new ArrayList<>(allowedActions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceId() {
|
||||
return stackId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDomainId() {
|
||||
return StackDomain.DOMAIN_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StackPermissionsImpl{"
|
||||
+ "userId='"
|
||||
+ getUserId()
|
||||
+ '\''
|
||||
+ ", stackId='"
|
||||
+ stackId
|
||||
+ '\''
|
||||
+ ", actions="
|
||||
+ actions
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,116 +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.workspace.server.filters;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.eclipse.che.multiuser.api.permission.server.SystemDomain.MANAGE_SYSTEM_ACTION;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SystemDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.DefaultRemovePermissionsChecker;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link PublicPermissionsRemoveChecker}.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class PublicPermissionsRemoveCheckerTest {
|
||||
|
||||
private static final String USER = "user123";
|
||||
private static final String INSTANCE = "instance123";
|
||||
|
||||
@Mock private Subject subj;
|
||||
@Mock private PermissionsManager manager;
|
||||
@Mock private DefaultRemovePermissionsChecker defaultChecker;
|
||||
|
||||
private PublicPermissionsRemoveChecker publicPermissionsRemoveChecker;
|
||||
|
||||
@BeforeMethod
|
||||
public void setup() throws Exception {
|
||||
publicPermissionsRemoveChecker = new PublicPermissionsRemoveChecker(defaultChecker, manager);
|
||||
final EnvironmentContext ctx = new EnvironmentContext();
|
||||
ctx.setSubject(subj);
|
||||
EnvironmentContext.setCurrent(ctx);
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void tearDown() throws Exception {
|
||||
EnvironmentContext.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permitsRemoveNonPublicPermissionsWhenDefaultCheckPassed() throws Exception {
|
||||
doNothing().when(defaultChecker).check(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
|
||||
publicPermissionsRemoveChecker.check(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
|
||||
verify(defaultChecker, times(1)).check(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
verify(manager, never()).get(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ForbiddenException.class)
|
||||
public void throwsForbiddenExceptionWhenRemoveNonPublicPermissionsAndDefaultCheckFailed()
|
||||
throws Exception {
|
||||
doThrow(ForbiddenException.class)
|
||||
.when(defaultChecker)
|
||||
.check(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
|
||||
publicPermissionsRemoveChecker.check(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
|
||||
verify(defaultChecker, times(1)).check(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
verify(manager, never()).get(USER, StackDomain.DOMAIN_ID, INSTANCE);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ForbiddenException.class)
|
||||
public void throwsForbiddenExceptionWhenFailedToGetActionRemovingPermissionByAdmin()
|
||||
throws Exception {
|
||||
doThrow(ServerException.class).when(manager).get("*", StackDomain.DOMAIN_ID, INSTANCE);
|
||||
doThrow(ForbiddenException.class)
|
||||
.when(defaultChecker)
|
||||
.check("*", StackDomain.DOMAIN_ID, INSTANCE);
|
||||
when(subj.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)).thenReturn(true);
|
||||
|
||||
publicPermissionsRemoveChecker.check("*", StackDomain.DOMAIN_ID, INSTANCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permitsRemoveStackPermissionsWhenAdminUserPassedDefaultCheck() throws Exception {
|
||||
when(manager.get("*", StackDomain.DOMAIN_ID, INSTANCE))
|
||||
.thenReturn(new StackPermissionsImpl("*", INSTANCE, singletonList(StackDomain.SEARCH)));
|
||||
when(subj.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)).thenReturn(true);
|
||||
|
||||
publicPermissionsRemoveChecker.check("*", StackDomain.DOMAIN_ID, INSTANCE);
|
||||
|
||||
verify(manager, times(1)).get("*", StackDomain.DOMAIN_ID, INSTANCE);
|
||||
verify(subj, times(1)).hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION);
|
||||
verify(defaultChecker, never()).check("*", StackDomain.DOMAIN_ID, INSTANCE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,172 +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.workspace.server.filters;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.eclipse.che.multiuser.api.permission.server.SystemDomain.MANAGE_SYSTEM_ACTION;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.SEARCH;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SystemDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.filter.check.DefaultSetPermissionsChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.model.Permissions;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link StackDomainSetPermissionsChecker}.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class StackDomainSetPermissionsCheckerTest {
|
||||
|
||||
@Mock private Subject subj;
|
||||
|
||||
@Mock private DefaultSetPermissionsChecker defaultChecker;
|
||||
|
||||
private StackDomainSetPermissionsChecker stackSetPermChecker;
|
||||
|
||||
@BeforeMethod
|
||||
public void setup() throws Exception {
|
||||
stackSetPermChecker = new StackDomainSetPermissionsChecker(defaultChecker);
|
||||
final EnvironmentContext ctx = new EnvironmentContext();
|
||||
ctx.setSubject(subj);
|
||||
EnvironmentContext.setCurrent(ctx);
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void tearDown() throws Exception {
|
||||
EnvironmentContext.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permitsToSetNonPublicPermissionsWhenDefaultCheckPassed() throws Exception {
|
||||
final Permissions permissions =
|
||||
new StackPermissionsImpl("user73", "stack73", singletonList(DELETE));
|
||||
doNothing().when(defaultChecker).check(permissions);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
|
||||
verify(defaultChecker).check(permissions);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ForbiddenException.class)
|
||||
public void throwsForbiddenExceptionOnSetNonPublicPermissionsWhenDefaultCheckFailed()
|
||||
throws Exception {
|
||||
final Permissions permissions =
|
||||
new StackPermissionsImpl("user73", "stack73", singletonList(DELETE));
|
||||
doThrow(ForbiddenException.class).when(defaultChecker).check(permissions);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permitsToSetPublicPermissionsWithSearchActionForAdmin() throws Exception {
|
||||
final Permissions permissions = new StackPermissionsImpl("*", "stack73", singletonList(SEARCH));
|
||||
when(subj.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)).thenReturn(true);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
|
||||
verify(subj).hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION);
|
||||
verify(defaultChecker, never()).check(permissions);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = ForbiddenException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Following actions are not supported for setting as public:.*")
|
||||
public void throwsForbiddenExceptionWhenSetPublicPermissionsWithUnsupportedActionByAdmin()
|
||||
throws Exception {
|
||||
final Permissions permissions =
|
||||
new StackPermissionsImpl("*", "stack73", ImmutableList.of(SEARCH, DELETE));
|
||||
when(subj.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)).thenReturn(true);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
|
||||
verify(subj).hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION);
|
||||
verify(defaultChecker, never()).check(permissions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permitsToSetPublicPermissionsWithReadActionForNonAdminUser() throws Exception {
|
||||
final Permissions permissions = new StackPermissionsImpl("*", "stack73", singletonList(READ));
|
||||
when(subj.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)).thenReturn(false);
|
||||
doNothing().when(defaultChecker).check(permissions);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
|
||||
verify(subj).hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION);
|
||||
verify(defaultChecker).check(permissions);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = ForbiddenException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Following actions are not supported for setting as public:.*")
|
||||
public void throwsForbiddenExceptionWhenSetPublicPermissionsWithUnsupportedActionByNonAdminUser()
|
||||
throws Exception {
|
||||
final Permissions permissions = new StackPermissionsImpl("*", "stack73", singletonList(DELETE));
|
||||
when(subj.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)).thenReturn(false);
|
||||
doNothing().when(defaultChecker).check(permissions);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
|
||||
verify(subj).hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION);
|
||||
verify(defaultChecker).check(permissions);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ForbiddenException.class)
|
||||
public void throwsForbiddenExceptionWhenSetPublicPermissionsByNonAdminUserFailedOnDefaultCheck()
|
||||
throws Exception {
|
||||
final Permissions permissions = new StackPermissionsImpl("*", "stack73", singletonList(READ));
|
||||
when(subj.hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION)).thenReturn(false);
|
||||
doThrow(ForbiddenException.class).when(defaultChecker).check(permissions);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
|
||||
verify(subj).hasPermission(SystemDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION);
|
||||
verify(defaultChecker).check(permissions);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ForbiddenException.class)
|
||||
public void throwsExceptionWhenChecksAdminPermissionsWithWrongDomainOnSetPermission()
|
||||
throws Exception {
|
||||
final Permissions permissions = new StackPermissionsImpl("*", "stack73", singletonList(SEARCH));
|
||||
lenient()
|
||||
.when(subj.hasPermission(StackDomain.DOMAIN_ID, null, MANAGE_SYSTEM_ACTION))
|
||||
.thenReturn(false);
|
||||
|
||||
stackSetPermChecker.check(permissions);
|
||||
|
||||
verify(subj).hasPermission(any(), any(), MANAGE_SYSTEM_ACTION);
|
||||
verify(defaultChecker).check(permissions);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,454 +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.workspace.server.filters;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.eclipse.che.multiuser.api.permission.server.SystemDomain.MANAGE_SYSTEM_ACTION;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.DOMAIN_ID;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.SEARCH;
|
||||
import static org.eclipse.che.multiuser.permission.workspace.server.stack.StackDomain.UPDATE;
|
||||
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.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.jayway.restassured.response.Response;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceService;
|
||||
import org.eclipse.che.api.workspace.server.stack.StackService;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SystemDomain;
|
||||
import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
import org.everrest.core.RequestFilter;
|
||||
import org.everrest.core.resource.GenericResourceMethod;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link StackPermissionsFilter}
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
* @author Mykola Morhun
|
||||
*/
|
||||
@Listeners(value = {EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class StackPermissionsFilterTest {
|
||||
@SuppressWarnings("unused")
|
||||
private static final ApiExceptionMapper MAPPER = new ApiExceptionMapper();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@InjectMocks
|
||||
StackPermissionsFilter permissionsFilter;
|
||||
|
||||
@Mock private static Subject subject;
|
||||
|
||||
@Mock private StackService service;
|
||||
@Mock private PermissionsManager permissionsManager;
|
||||
|
||||
@BeforeMethod
|
||||
public void beforeMethod() throws Exception {
|
||||
permissionsFilter = spy(new StackPermissionsFilter(permissionsManager));
|
||||
|
||||
lenient().doReturn(false).when(subject).hasPermission("stack", "stack123", SEARCH);
|
||||
lenient().doReturn(false).when(subject).hasPermission("system", null, MANAGE_SYSTEM_ACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCheckPermissionsOnStackCreating() throws Exception {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.post(SECURE_PATH + "/stack");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(service).createStack(any());
|
||||
verifyZeroInteractions(subject);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckPermissionsOnStackReading() throws Exception {
|
||||
when(subject.hasPermission("stack", "stack123", READ)).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack/stack123");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(service).getStack("stack123");
|
||||
verify(subject).hasPermission(eq("stack"), eq("stack123"), eq(READ));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckPermissionsOnStackUpdating() throws Exception {
|
||||
when(subject.hasPermission("stack", "stack123", UPDATE)).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.put(SECURE_PATH + "/stack/stack123");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(service).updateStack(any(), eq("stack123"));
|
||||
verify(subject).hasPermission(eq("stack"), eq("stack123"), eq(UPDATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckPermissionsOnStackRemoving() throws Exception {
|
||||
when(subject.hasPermission("stack", "stack123", DELETE)).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/stack/stack123");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(service).removeStack(eq("stack123"));
|
||||
verify(subject).hasPermission(eq("stack"), eq("stack123"), eq(DELETE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCheckPermissionsOnStacksSearching() throws Exception {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(service).searchStacks(nullable(List.class), anyInt(), anyInt());
|
||||
verifyZeroInteractions(subject);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckPermissionsOnIconReading() throws Exception {
|
||||
when(subject.hasPermission("stack", "stack123", READ)).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack/stack123/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(service).getIcon(eq("stack123"));
|
||||
verify(subject).hasPermission(eq("stack"), eq("stack123"), eq(READ));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckPermissionsOnIconUploading() throws Exception {
|
||||
when(subject.hasPermission("stack", "stack123", UPDATE)).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("multipart/form-data")
|
||||
.multiPart("icon", "content", "image/png")
|
||||
.when()
|
||||
.post(SECURE_PATH + "/stack/stack123/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(service).uploadIcon(any(), eq("stack123"));
|
||||
verify(subject).hasPermission(eq("stack"), eq("stack123"), eq(UPDATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowForbiddenExceptionWhenUserDoesNotHavePermissionsForIconUpdating() {
|
||||
when(subject.hasPermission("stack", "stack123", UPDATE)).thenReturn(false);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("multipart/form-data")
|
||||
.multiPart("icon", "content", "image/png")
|
||||
.when()
|
||||
.post(SECURE_PATH + "/stack/stack123/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 403);
|
||||
Assert.assertEquals(
|
||||
unwrapError(response),
|
||||
"The user does not have permission to " + UPDATE + " stack with id 'stack123'");
|
||||
verifyZeroInteractions(service);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckPermissionsOnIconRemoving() throws Exception {
|
||||
when(subject.hasPermission("stack", "stack123", UPDATE)).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("multipart/form-data")
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/stack/stack123/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(service).removeIcon(eq("stack123"));
|
||||
verify(subject).hasPermission(eq("stack"), eq("stack123"), eq(UPDATE));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = ForbiddenException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"The user does not have permission to perform this operation")
|
||||
public void shouldThrowForbiddenExceptionWhenRequestedUnknownMethod() throws Exception {
|
||||
final GenericResourceMethod mock = mock(GenericResourceMethod.class);
|
||||
Method injectLinks = WorkspaceService.class.getMethod("getServiceDescriptor");
|
||||
when(mock.getMethod()).thenReturn(injectLinks);
|
||||
|
||||
permissionsFilter.filter(mock, new Object[] {});
|
||||
}
|
||||
|
||||
@Test(dataProvider = "coveredPaths")
|
||||
public void shouldThrowForbiddenExceptionWhenUserDoesNotHavePermissionsForPerformOperation(
|
||||
String path, String method, String action) throws Exception {
|
||||
when(subject.hasPermission(
|
||||
nullable(String.class), nullable(String.class), nullable(String.class)))
|
||||
.thenReturn(false);
|
||||
|
||||
Response response =
|
||||
request(
|
||||
given().auth().basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD).when(),
|
||||
SECURE_PATH + path,
|
||||
method);
|
||||
|
||||
assertEquals(response.getStatusCode(), 403);
|
||||
assertEquals(
|
||||
unwrapError(response),
|
||||
"The user does not have permission to " + action + " stack with id 'stack123'");
|
||||
verifyZeroInteractions(service);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "coveredPaths")
|
||||
public void shouldAllowToAdminPerformAnyActionWithPredefinedStack(
|
||||
String path, String method, String action) throws Exception {
|
||||
doReturn(false)
|
||||
.when(subject)
|
||||
.hasPermission(eq(DOMAIN_ID), nullable(String.class), nullable(String.class));
|
||||
doReturn(true)
|
||||
.when(subject)
|
||||
.hasPermission(eq(SystemDomain.DOMAIN_ID), nullable(String.class), nullable(String.class));
|
||||
doReturn(true).when(permissionsFilter).isStackPredefined(nullable(String.class));
|
||||
|
||||
Response response =
|
||||
request(
|
||||
given().auth().basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD).when(),
|
||||
SECURE_PATH + path,
|
||||
method);
|
||||
|
||||
assertEquals(response.getStatusCode() / 100, 2);
|
||||
verify(subject).hasPermission(eq(SystemDomain.DOMAIN_ID), eq(null), eq(MANAGE_SYSTEM_ACTION));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "coveredPaths")
|
||||
public void shouldNotAllowToAdminPerformAnyActionWithNonPredefinedStack(
|
||||
String path, String method, String action) throws Exception {
|
||||
doReturn(false)
|
||||
.when(subject)
|
||||
.hasPermission(eq(DOMAIN_ID), nullable(String.class), nullable(String.class));
|
||||
doReturn(true)
|
||||
.when(subject)
|
||||
.hasPermission(eq(SystemDomain.DOMAIN_ID), nullable(String.class), nullable(String.class));
|
||||
doReturn(false).when(permissionsFilter).isStackPredefined(nullable(String.class));
|
||||
|
||||
Response response =
|
||||
request(
|
||||
given().auth().basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD).when(),
|
||||
SECURE_PATH + path,
|
||||
method);
|
||||
|
||||
assertEquals(response.getStatusCode(), 403);
|
||||
verify(subject).hasPermission(eq(SystemDomain.DOMAIN_ID), eq(null), eq(MANAGE_SYSTEM_ACTION));
|
||||
}
|
||||
|
||||
@DataProvider(name = "coveredPaths")
|
||||
public Object[][] pathsProvider() {
|
||||
return new Object[][] {
|
||||
{"/stack/stack123", "get", READ},
|
||||
{"/stack/stack123", "put", UPDATE},
|
||||
{"/stack/stack123", "delete", DELETE},
|
||||
{"/stack/stack123/icon", "get", READ},
|
||||
{"/stack/stack123/icon", "delete", UPDATE}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRecognizePredefinedStack() throws Exception {
|
||||
final AbstractPermissions stackPermission = mock(AbstractPermissions.class);
|
||||
when(stackPermission.getUserId()).thenReturn("*");
|
||||
|
||||
final Page<AbstractPermissions> permissionsPage = mock(Page.class);
|
||||
when(permissionsPage.getItems()).thenReturn(Collections.singletonList(stackPermission));
|
||||
|
||||
when(permissionsManager.getByInstance(
|
||||
nullable(String.class), nullable(String.class), anyInt(), anyLong()))
|
||||
.thenReturn(permissionsPage);
|
||||
|
||||
assertTrue(permissionsFilter.isStackPredefined("stack123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRecognizeNonPredefinedStack() throws Exception {
|
||||
final AbstractPermissions stackPermission = mock(AbstractPermissions.class);
|
||||
when(stackPermission.getUserId()).thenReturn("userId");
|
||||
|
||||
final Page<AbstractPermissions> permissionsPage = mock(Page.class);
|
||||
when(permissionsPage.getItems()).thenReturn(Collections.singletonList(stackPermission));
|
||||
|
||||
when(permissionsManager.getByInstance(
|
||||
nullable(String.class), nullable(String.class), anyInt(), anyLong()))
|
||||
.thenReturn(permissionsPage);
|
||||
|
||||
assertFalse(permissionsFilter.isStackPredefined("stack123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRecognizePredefinedStackWhenAFewPermissionsPagesIsRetrieved() throws Exception {
|
||||
final String stackId = "stack123";
|
||||
|
||||
final AbstractPermissions privateStackPermission = mock(AbstractPermissions.class);
|
||||
when(privateStackPermission.getUserId()).thenReturn("userId");
|
||||
|
||||
final AbstractPermissions publicStackPermission = mock(AbstractPermissions.class);
|
||||
when(publicStackPermission.getUserId()).thenReturn("*");
|
||||
|
||||
final Page<AbstractPermissions> permissionsPage1 = mock(Page.class);
|
||||
when(permissionsPage1.getItems())
|
||||
.thenReturn(asList(privateStackPermission, privateStackPermission, privateStackPermission));
|
||||
when(permissionsPage1.hasNextPage()).thenReturn(true);
|
||||
|
||||
final Page<AbstractPermissions> permissionsPage2 = mock(Page.class);
|
||||
when(permissionsPage2.getItems())
|
||||
.thenReturn(asList(privateStackPermission, publicStackPermission, privateStackPermission));
|
||||
when(permissionsPage2.hasNextPage()).thenReturn(false);
|
||||
|
||||
doReturn(permissionsPage2)
|
||||
.when(permissionsFilter)
|
||||
.getNextPermissionsPage(stackId, permissionsPage1);
|
||||
doReturn(null).when(permissionsFilter).getNextPermissionsPage(stackId, permissionsPage2);
|
||||
when(permissionsManager.getByInstance(
|
||||
nullable(String.class), nullable(String.class), anyInt(), anyLong()))
|
||||
.thenReturn(permissionsPage1);
|
||||
|
||||
assertTrue(permissionsFilter.isStackPredefined(stackId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToRetrieveNextPermissionPage() throws Exception {
|
||||
final String stackId = "stack123";
|
||||
|
||||
final Page<AbstractPermissions> currentPage = mock(Page.class);
|
||||
when(currentPage.hasNextPage()).thenReturn(true);
|
||||
when(currentPage.getNextPageRef()).thenReturn(mock(Page.PageRef.class));
|
||||
|
||||
final Page<AbstractPermissions> nextPage = mock(Page.class);
|
||||
when(permissionsManager.getByInstance(eq(DOMAIN_ID), eq(stackId), anyInt(), anyLong()))
|
||||
.thenReturn(nextPage);
|
||||
|
||||
assertEquals(permissionsFilter.getNextPermissionsPage(stackId, currentPage), nextPage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnNullIfNoNextPermissionPage() throws Exception {
|
||||
final Page<AbstractPermissions> currentPage = mock(Page.class);
|
||||
when(currentPage.hasNextPage()).thenReturn(false);
|
||||
|
||||
assertNull(permissionsFilter.getNextPermissionsPage("stack123", currentPage));
|
||||
}
|
||||
|
||||
private Response request(RequestSpecification request, String path, String method) {
|
||||
switch (method) {
|
||||
case "post":
|
||||
return request.post(path);
|
||||
case "get":
|
||||
return request.get(path);
|
||||
case "delete":
|
||||
return request.delete(path);
|
||||
case "put":
|
||||
return request.put(path);
|
||||
}
|
||||
throw new RuntimeException("Unsupported method");
|
||||
}
|
||||
|
||||
private static String unwrapError(Response response) {
|
||||
return unwrapDto(response, ServiceError.class).getMessage();
|
||||
}
|
||||
|
||||
private static <T> T unwrapDto(Response response, Class<T> dtoClass) {
|
||||
return DtoFactory.getInstance().createDtoFromJson(response.body().print(), dtoClass);
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,180 +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.workspace.server.jpa;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.event.BeforeStackRemovedEvent;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaStackPermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
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;
|
||||
|
||||
/** @author Max Shaposhnik */
|
||||
public class JpaStackPermissionsDaoTest {
|
||||
private TckResourcesCleaner tckResourcesCleaner;
|
||||
|
||||
private EntityManager manager;
|
||||
|
||||
private JpaStackPermissionsDao dao;
|
||||
|
||||
private JpaStackPermissionsDao.RemovePermissionsBeforeStackRemovedEventSubscriber
|
||||
removePermissionsSubscriber;
|
||||
|
||||
private StackPermissionsImpl[] permissions;
|
||||
private UserImpl[] users;
|
||||
private StackImpl[] stacks;
|
||||
|
||||
@BeforeClass
|
||||
public void setupEntities() throws Exception {
|
||||
permissions =
|
||||
new StackPermissionsImpl[] {
|
||||
new StackPermissionsImpl("user1", "stack1", asList("read", "use", "run")),
|
||||
new StackPermissionsImpl("user2", "stack1", asList("read", "use")),
|
||||
new StackPermissionsImpl("user1", "stack2", asList("read", "run")),
|
||||
new StackPermissionsImpl("user2", "stack2", asList("read", "use", "run", "configure"))
|
||||
};
|
||||
|
||||
users =
|
||||
new UserImpl[] {
|
||||
new UserImpl("user1", "user1@com.com", "usr1"),
|
||||
new UserImpl("user2", "user2@com.com", "usr2")
|
||||
};
|
||||
|
||||
stacks =
|
||||
new StackImpl[] {
|
||||
new StackImpl("stack1", "st1", null, null, null, null, null, null, null),
|
||||
new StackImpl("stack2", "st2", null, null, null, null, null, null, null)
|
||||
};
|
||||
|
||||
Injector injector = Guice.createInjector(new WorkspaceTckModule());
|
||||
manager = injector.getInstance(EntityManager.class);
|
||||
dao = injector.getInstance(JpaStackPermissionsDao.class);
|
||||
removePermissionsSubscriber =
|
||||
injector.getInstance(
|
||||
JpaStackPermissionsDao.RemovePermissionsBeforeStackRemovedEventSubscriber.class);
|
||||
tckResourcesCleaner = injector.getInstance(TckResourcesCleaner.class);
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
manager.getTransaction().begin();
|
||||
for (UserImpl user : users) {
|
||||
manager.persist(user);
|
||||
}
|
||||
|
||||
for (StackImpl stack : stacks) {
|
||||
manager.persist(stack);
|
||||
}
|
||||
|
||||
for (StackPermissionsImpl stackPermissions : permissions) {
|
||||
manager.persist(stackPermissions);
|
||||
}
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() {
|
||||
manager.getTransaction().begin();
|
||||
|
||||
manager
|
||||
.createQuery("SELECT p FROM StackPermissions p", StackPermissionsImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager
|
||||
.createQuery("SELECT r FROM Stack r", StackImpl.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 {
|
||||
tckResourcesCleaner.clean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveStackPermissionsWhenStackIsRemoved() throws Exception {
|
||||
BeforeStackRemovedEvent event = new BeforeStackRemovedEvent(stacks[0]);
|
||||
removePermissionsSubscriber.onEvent(event);
|
||||
assertTrue(dao.getByInstance("stack1", 30, 0).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldStoreStackPublicPermission() throws Exception {
|
||||
final StackPermissionsImpl publicPermission =
|
||||
new StackPermissionsImpl("*", "stack1", asList("read", "use", "run"));
|
||||
dao.store(publicPermission);
|
||||
|
||||
assertTrue(
|
||||
dao.getByInstance(publicPermission.getInstanceId(), 30, 0)
|
||||
.getItems()
|
||||
.contains(new StackPermissionsImpl(publicPermission)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateExistingStackPublicPermissions() throws Exception {
|
||||
final StackPermissionsImpl publicPermission =
|
||||
new StackPermissionsImpl("*", "stack1", asList("read", "use", "run"));
|
||||
dao.store(publicPermission);
|
||||
dao.store(publicPermission);
|
||||
|
||||
final Page<StackPermissionsImpl> permissions =
|
||||
dao.getByInstance(publicPermission.getInstanceId(), 30, 0);
|
||||
assertTrue(permissions.getItems().contains(new StackPermissionsImpl(publicPermission)));
|
||||
assertTrue(permissions.getItems().stream().filter(p -> "*".equals(p.getUserId())).count() == 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveStackPublicPermission() throws Exception {
|
||||
final StackPermissionsImpl publicPermission =
|
||||
new StackPermissionsImpl("*", "stack1", asList("read", "use", "run"));
|
||||
dao.store(publicPermission);
|
||||
dao.remove(publicPermission.getUserId(), publicPermission.getInstanceId());
|
||||
|
||||
Page<StackPermissionsImpl> byInstance =
|
||||
dao.getByInstance(publicPermission.getInstanceId(), 30, 0);
|
||||
assertTrue(byInstance.getItems().stream().filter(p -> "*".equals(p.getUserId())).count() == 0);
|
||||
}
|
||||
|
||||
public static class TestDomain extends AbstractPermissionsDomain<StackPermissionsImpl> {
|
||||
public TestDomain() {
|
||||
super("stack", asList("read", "write", "use", "delete"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackPermissionsImpl doCreateInstance(
|
||||
String userId, String instanceId, List<String> allowedActions) {
|
||||
return new StackPermissionsImpl(userId, instanceId, allowedActions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,195 +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.workspace.server.jpa;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
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.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.MultiuserJpaStackDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
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;
|
||||
|
||||
/** @author Max Shaposhnik (mshaposhnik@codenvy.com) */
|
||||
public class MultiuserJpaStackDaoTest {
|
||||
|
||||
private TckResourcesCleaner tckResourcesCleaner;
|
||||
private EntityManager manager;
|
||||
private MultiuserJpaStackDao dao;
|
||||
|
||||
private UserImpl[] users;
|
||||
private StackImpl[] stacks;
|
||||
|
||||
@BeforeClass
|
||||
public void setupEntities() throws Exception {
|
||||
users =
|
||||
new UserImpl[] {
|
||||
new UserImpl("user1", "user1@com.com", "usr1"),
|
||||
new UserImpl("user2", "user2@com.com", "usr2")
|
||||
};
|
||||
|
||||
stacks =
|
||||
new StackImpl[] {
|
||||
new StackImpl(
|
||||
"stack1", "st1", null, null, null, Arrays.asList("tag1", "tag2"), null, null, null),
|
||||
new StackImpl("stack2", "st2", null, null, null, null, null, null, null),
|
||||
new StackImpl(
|
||||
"stack3", "st3", null, null, null, Arrays.asList("tag1", "tag2"), null, null, null),
|
||||
new StackImpl("stack4", "st4", null, null, null, null, null, null, null)
|
||||
};
|
||||
|
||||
Injector injector = Guice.createInjector(new WorkspaceTckModule());
|
||||
manager = injector.getInstance(EntityManager.class);
|
||||
dao = injector.getInstance(MultiuserJpaStackDao.class);
|
||||
tckResourcesCleaner = injector.getInstance(TckResourcesCleaner.class);
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
manager.getTransaction().begin();
|
||||
for (UserImpl user : users) {
|
||||
manager.persist(user);
|
||||
}
|
||||
|
||||
for (StackImpl recipe : stacks) {
|
||||
manager.persist(recipe);
|
||||
}
|
||||
|
||||
manager.getTransaction().commit();
|
||||
manager.clear();
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() {
|
||||
manager.getTransaction().begin();
|
||||
|
||||
manager
|
||||
.createQuery("SELECT p FROM StackPermissions p", StackPermissionsImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
|
||||
manager
|
||||
.createQuery("SELECT r FROM Stack r", StackImpl.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 {
|
||||
tckResourcesCleaner.clean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindStackByDirectPermissions() throws Exception {
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[0].getId(), Arrays.asList("read", "use", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[1].getId(), Arrays.asList("read", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[2].getId(), Arrays.asList("read", "search")));
|
||||
|
||||
List<StackImpl> results = dao.searchStacks(users[0].getId(), null, 0, 0);
|
||||
|
||||
assertEquals(results.size(), 3);
|
||||
assertTrue(results.contains(stacks[0]));
|
||||
assertTrue(results.contains(stacks[1]));
|
||||
assertTrue(results.contains(stacks[2]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindStackByPublicPermissions() throws Exception {
|
||||
manager.persist(
|
||||
new StackPermissionsImpl("*", stacks[0].getId(), Arrays.asList("read", "use", "search")));
|
||||
|
||||
List<StackImpl> results = dao.searchStacks(users[0].getId(), null, 0, 0);
|
||||
|
||||
assertEquals(results.size(), 1);
|
||||
assertTrue(results.contains(stacks[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindStackByPublicAndDirectPermissions() throws Exception {
|
||||
manager.persist(
|
||||
new StackPermissionsImpl("*", stacks[0].getId(), Arrays.asList("read", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[0].getId(), Arrays.asList("read", "search")));
|
||||
|
||||
List<StackImpl> results = dao.searchStacks(users[0].getId(), null, 0, 0);
|
||||
assertEquals(results.size(), 1);
|
||||
assertTrue(results.contains(stacks[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindRecipeByPermissionsAndTags() throws Exception {
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[0].getId(), Arrays.asList("read", "use", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[1].getId(), Arrays.asList("read", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[2].getId(), Arrays.asList("read", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[3].getId(), Arrays.asList("read", "search")));
|
||||
|
||||
List<StackImpl> results =
|
||||
dao.searchStacks(users[0].getId(), Collections.singletonList("tag2"), 0, 0);
|
||||
assertEquals(results.size(), 2);
|
||||
assertTrue(results.contains(stacks[0]));
|
||||
assertTrue(results.contains(stacks[2]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotFindRecipeByNonexistentTags() throws Exception {
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[0].getId(), Arrays.asList("read", "use", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[1].getId(), Arrays.asList("read", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[2].getId(), Arrays.asList("read", "search")));
|
||||
manager.persist(
|
||||
new StackPermissionsImpl(
|
||||
users[0].getId(), stacks[3].getId(), Arrays.asList("read", "search")));
|
||||
|
||||
List<StackImpl> results =
|
||||
dao.searchStacks(users[0].getId(), Collections.singletonList("unexisted_tag2"), 0, 0);
|
||||
|
||||
assertTrue(results.isEmpty());
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@ import java.util.Collection;
|
|||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
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.jpa.JpaStackDao;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
|
||||
|
|
@ -36,8 +35,6 @@ 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.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
|
|
@ -52,14 +49,10 @@ 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.api.permission.server.spi.PermissionsDao;
|
||||
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.JpaStackPermissionsDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaWorkerDao;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.tck.StackPermissionsDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.tck.WorkerDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.h2.Driver;
|
||||
|
||||
/** @author Yevhenii Voevodin */
|
||||
|
|
@ -79,12 +72,10 @@ public class WorkspaceTckModule extends TckModule {
|
|||
WorkspaceConfigImpl.class,
|
||||
ProjectConfigImpl.class,
|
||||
EnvironmentImpl.class,
|
||||
StackPermissionsImpl.class,
|
||||
WorkerImpl.class,
|
||||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
StackImpl.class,
|
||||
CommandImpl.class,
|
||||
RecipeImpl.class,
|
||||
VolumeImpl.class,
|
||||
|
|
@ -112,25 +103,16 @@ public class WorkspaceTckModule extends TckModule {
|
|||
bind(new TypeLiteral<TckRepository<AccountImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(AccountImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {}).toInstance(new WorkspaceRepository());
|
||||
bind(new TypeLiteral<TckRepository<StackImpl>>() {}).toInstance(new StackRepository());
|
||||
bind(new TypeLiteral<TckRepository<UserImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(UserImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<WorkerImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(WorkerImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<StackPermissionsImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(StackPermissionsImpl.class));
|
||||
|
||||
bind(new TypeLiteral<PermissionsDao<StackPermissionsImpl>>() {})
|
||||
.to(JpaStackPermissionsDao.class);
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<WorkerImpl>>() {})
|
||||
.to(WorkerDaoTest.TestDomain.class);
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<StackPermissionsImpl>>() {})
|
||||
.to(StackPermissionsDaoTest.TestDomain.class);
|
||||
|
||||
bind(WorkerDao.class).to(JpaWorkerDao.class);
|
||||
bind(WorkspaceDao.class).to(JpaWorkspaceDao.class);
|
||||
bind(StackDao.class).to(JpaStackDao.class);
|
||||
}
|
||||
|
||||
private static class WorkspaceRepository extends JpaTckRepository<WorkspaceImpl> {
|
||||
|
|
@ -147,18 +129,4 @@ public class WorkspaceTckModule extends TckModule {
|
|||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StackRepository extends JpaTckRepository<StackImpl> {
|
||||
public StackRepository() {
|
||||
super(StackImpl.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAll(Collection<? extends StackImpl> entities) throws TckRepositoryException {
|
||||
for (StackImpl stack : entities) {
|
||||
stack.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ 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.stack.StackImpl;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
import org.eclipse.che.commons.test.db.PersistTestModuleBuilder;
|
||||
|
|
@ -46,12 +45,9 @@ 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.api.permission.server.spi.PermissionsDao;
|
||||
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.tck.StackPermissionsDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.tck.WorkerDaoTest;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.h2.Driver;
|
||||
|
||||
/** @author Yevhenii Voevodin */
|
||||
|
|
@ -71,12 +67,10 @@ public class JpaTckModule extends TckModule {
|
|||
WorkspaceConfigImpl.class,
|
||||
ProjectConfigImpl.class,
|
||||
EnvironmentImpl.class,
|
||||
StackPermissionsImpl.class,
|
||||
WorkerImpl.class,
|
||||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
StackImpl.class,
|
||||
CommandImpl.class,
|
||||
RecipeImpl.class,
|
||||
VolumeImpl.class,
|
||||
|
|
@ -97,15 +91,6 @@ public class JpaTckModule extends TckModule {
|
|||
.setExceptionHandler(H2ExceptionHandler.class)
|
||||
.build());
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<StackPermissionsImpl>>() {})
|
||||
.to(StackPermissionsDaoTest.TestDomain.class);
|
||||
bind(new TypeLiteral<PermissionsDao<StackPermissionsImpl>>() {})
|
||||
.to(JpaStackPermissionsDao.class);
|
||||
bind(new TypeLiteral<TckRepository<StackPermissionsImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(StackPermissionsImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<StackImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(StackImpl.class));
|
||||
|
||||
bind(new TypeLiteral<AbstractPermissionsDomain<WorkerImpl>>() {})
|
||||
.to(WorkerDaoTest.TestDomain.class);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,126 +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.workspace.server.spi.jpa;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import javax.persistence.EntityManager;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaStackDao;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.commons.test.tck.TckResourcesCleaner;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.spi.jpa.JpaStackPermissionsDao.RemovePermissionsBeforeStackRemovedEventSubscriber;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
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 RemovePermissionsBeforeStackRemovedEventSubscriber}
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public class RemovePermissionsBeforeStackRemovedEventSubscriberTest {
|
||||
private TckResourcesCleaner tckResourcesCleaner;
|
||||
private EntityManager manager;
|
||||
private JpaStackDao stackDao;
|
||||
private JpaStackPermissionsDao stackPermissionsDao;
|
||||
|
||||
private RemovePermissionsBeforeStackRemovedEventSubscriber subscriber;
|
||||
|
||||
private StackImpl stack;
|
||||
private UserImpl[] users;
|
||||
private StackPermissionsImpl[] stackPermissions;
|
||||
|
||||
@BeforeClass
|
||||
public void setupEntities() throws Exception {
|
||||
stack = StackImpl.builder().setId("stack123").setName("defaultStack").build();
|
||||
users = new UserImpl[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
users[i] = new UserImpl("user" + i, "user" + i + "@test.com", "username" + i);
|
||||
}
|
||||
stackPermissions = new StackPermissionsImpl[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
stackPermissions[i] =
|
||||
new StackPermissionsImpl(users[i].getId(), stack.getId(), asList("read", "update"));
|
||||
}
|
||||
|
||||
Injector injector = Guice.createInjector(new JpaTckModule());
|
||||
|
||||
manager = injector.getInstance(EntityManager.class);
|
||||
stackDao = injector.getInstance(JpaStackDao.class);
|
||||
stackPermissionsDao = injector.getInstance(JpaStackPermissionsDao.class);
|
||||
tckResourcesCleaner = injector.getInstance(TckResourcesCleaner.class);
|
||||
|
||||
subscriber = injector.getInstance(RemovePermissionsBeforeStackRemovedEventSubscriber.class);
|
||||
subscriber.subscribe();
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
manager.getTransaction().begin();
|
||||
manager.persist(stack);
|
||||
Stream.of(users).forEach(manager::persist);
|
||||
Stream.of(stackPermissions).forEach(manager::persist);
|
||||
manager.getTransaction().commit();
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() {
|
||||
manager.getTransaction().begin();
|
||||
manager
|
||||
.createQuery("SELECT usr FROM Usr usr", UserImpl.class)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
manager.getTransaction().commit();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void shutdown() throws Exception {
|
||||
subscriber.unsubscribe();
|
||||
tckResourcesCleaner.clean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveAllRecipePermissionsWhenRecipeIsRemoved() throws Exception {
|
||||
stackDao.remove(stack.getId());
|
||||
|
||||
assertEquals(stackPermissionsDao.getByInstance(stack.getId(), 1, 0).getTotalItemsCount(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveAllRecipePermissionsWhenPageSizeEqualsToOne() throws Exception {
|
||||
subscriber.removeStackPermissions(stack.getId(), 1);
|
||||
|
||||
assertEquals(stackPermissionsDao.getByInstance(stack.getId(), 1, 0).getTotalItemsCount(), 0);
|
||||
}
|
||||
|
||||
public static class TestDomain extends AbstractPermissionsDomain<StackPermissionsImpl> {
|
||||
public TestDomain() {
|
||||
super("stack", asList("read", "write", "use", "delete"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackPermissionsImpl doCreateInstance(
|
||||
String userId, String instanceId, List<String> allowedActions) {
|
||||
return new StackPermissionsImpl(userId, instanceId, allowedActions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,255 +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.workspace.server.spi.tck;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
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.stack.StackImpl;
|
||||
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.api.permission.server.spi.PermissionsDao;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.model.Permissions;
|
||||
import org.eclipse.che.multiuser.permission.workspace.server.stack.StackPermissionsImpl;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/** @author Max Shaposhnik */
|
||||
@Listeners(TckListener.class)
|
||||
@Test(suiteName = "StackPermissionsDaoTck")
|
||||
public class StackPermissionsDaoTest {
|
||||
|
||||
@Inject private PermissionsDao<StackPermissionsImpl> dao;
|
||||
@Inject private TckRepository<StackPermissionsImpl> permissionsRepository;
|
||||
@Inject private TckRepository<UserImpl> userRepository;
|
||||
@Inject private TckRepository<StackImpl> stackRepository;
|
||||
|
||||
private StackPermissionsImpl[] permissions;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws TckRepositoryException {
|
||||
permissions =
|
||||
new StackPermissionsImpl[] {
|
||||
new StackPermissionsImpl("user1", "stack1", asList("read", "use", "run")),
|
||||
new StackPermissionsImpl("user2", "stack1", asList("read", "use")),
|
||||
new StackPermissionsImpl("user1", "stack2", asList("read", "run")),
|
||||
new StackPermissionsImpl("user2", "stack2", asList("read", "use", "run", "configure")),
|
||||
new StackPermissionsImpl("user", "stack2", asList("read", "use", "run", "configure"))
|
||||
};
|
||||
|
||||
final UserImpl[] users =
|
||||
new UserImpl[] {
|
||||
new UserImpl("user", "user@com.com", "usr"),
|
||||
new UserImpl("user1", "user1@com.com", "usr1"),
|
||||
new UserImpl("user2", "user2@com.com", "usr2")
|
||||
};
|
||||
userRepository.createAll(asList(users));
|
||||
|
||||
// Workspace configuration
|
||||
final WorkspaceConfigImpl wCfg = new WorkspaceConfigImpl();
|
||||
wCfg.setDefaultEnv("env1");
|
||||
wCfg.setName("ws1");
|
||||
wCfg.setDescription("description");
|
||||
stackRepository.createAll(
|
||||
asList(
|
||||
new StackImpl("stack1", "st1", null, null, null, null, wCfg, null, null),
|
||||
new StackImpl("stack2", "st2", null, null, null, null, wCfg, null, null)));
|
||||
|
||||
permissionsRepository.createAll(
|
||||
Stream.of(permissions).map(StackPermissionsImpl::new).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanUp() throws TckRepositoryException {
|
||||
permissionsRepository.removeAll();
|
||||
stackRepository.removeAll();
|
||||
userRepository.removeAll();
|
||||
}
|
||||
|
||||
/* StackPermissionsDao.store() tests */
|
||||
@Test
|
||||
public void shouldStorePermissions() throws Exception {
|
||||
final StackPermissionsImpl permissions =
|
||||
new StackPermissionsImpl("user", "stack1", asList("read", "use"));
|
||||
|
||||
dao.store(permissions);
|
||||
|
||||
final Permissions result = dao.get(permissions.getUserId(), permissions.getInstanceId());
|
||||
assertEquals(result, new StackPermissionsImpl(permissions));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenStoringArgumentIsNull() throws Exception {
|
||||
dao.store(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReplacePermissionsOnStoringWhenItHasAlreadyExisted() throws Exception {
|
||||
StackPermissionsImpl oldPermissions = permissions[0];
|
||||
|
||||
StackPermissionsImpl newPermissions =
|
||||
new StackPermissionsImpl(
|
||||
oldPermissions.getUserId(), oldPermissions.getInstanceId(), singletonList("read"));
|
||||
dao.store(newPermissions);
|
||||
|
||||
final Permissions result = dao.get(oldPermissions.getUserId(), oldPermissions.getInstanceId());
|
||||
|
||||
assertEquals(newPermissions, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnsSupportedDomainsIds() {
|
||||
assertEquals(dao.getDomain(), new TestDomain());
|
||||
}
|
||||
|
||||
/* StackPermissionsDao.remove() tests */
|
||||
@Test
|
||||
public void shouldRemovePermissions() throws Exception {
|
||||
StackPermissionsImpl testPermission = permissions[3];
|
||||
|
||||
dao.remove(testPermission.getUserId(), testPermission.getInstanceId());
|
||||
|
||||
assertFalse(
|
||||
dao.exists(
|
||||
testPermission.getUserId(),
|
||||
testPermission.getInstanceId(),
|
||||
testPermission.getActions().get(0)));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = NotFoundException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Permissions on stack 'instance' of user 'user' was not found.")
|
||||
public void shouldThrowNotFoundExceptionWhenPermissionsWasNotFoundOnRemove() throws Exception {
|
||||
dao.remove("user", "instance");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenRemovePermissionsUserIdArgumentIsNull() throws Exception {
|
||||
dao.remove(null, "instance");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenRemovePermissionsInstanceIdArgumentIsNull() throws Exception {
|
||||
dao.remove("user", null);
|
||||
}
|
||||
|
||||
/* StackPermissionsDao.getByInstance() tests */
|
||||
@Test
|
||||
public void shouldGetPermissionsByInstance() throws Exception {
|
||||
final Page<StackPermissionsImpl> permissionsPage =
|
||||
dao.getByInstance(permissions[2].getInstanceId(), 1, 1);
|
||||
final List<StackPermissionsImpl> fetchedPermissions = permissionsPage.getItems();
|
||||
|
||||
assertEquals(3, permissionsPage.getTotalItemsCount());
|
||||
assertEquals(1, permissionsPage.getItemsCount());
|
||||
assertTrue(
|
||||
fetchedPermissions.contains(permissions[2])
|
||||
^ fetchedPermissions.contains(this.permissions[3])
|
||||
^ fetchedPermissions.contains(this.permissions[4]));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenGetByInstanceInstanceIdArgumentIsNull() throws Exception {
|
||||
dao.getByInstance(null, 1, 0);
|
||||
}
|
||||
|
||||
/* StackPermissionsDao.get() tests */
|
||||
@Test
|
||||
public void shouldBeAbleToGetPermissions() throws Exception {
|
||||
|
||||
final StackPermissionsImpl result1 =
|
||||
dao.get(permissions[0].getUserId(), permissions[0].getInstanceId());
|
||||
final StackPermissionsImpl result2 =
|
||||
dao.get(permissions[2].getUserId(), permissions[2].getInstanceId());
|
||||
|
||||
assertEquals(result1, permissions[0]);
|
||||
assertEquals(result2, permissions[2]);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = NotFoundException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Permissions on stack 'instance' of user 'user' was not found.")
|
||||
public void
|
||||
shouldThrowNotFoundExceptionWhenThereIsNotAnyPermissionsForGivenUserAndDomainAndInstance()
|
||||
throws Exception {
|
||||
dao.get("user", "instance");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenGetPermissionsUserIdArgumentIsNull() throws Exception {
|
||||
dao.get(null, "instance");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenGetPermissionsInstanceIdArgumentIsNull() throws Exception {
|
||||
dao.get("user", null);
|
||||
}
|
||||
|
||||
/* StackPermissionsDao.exists() tests */
|
||||
@Test
|
||||
public void shouldBeAbleToCheckPermissionExistence() throws Exception {
|
||||
|
||||
StackPermissionsImpl testPermission = permissions[0];
|
||||
|
||||
final boolean readPermissionExisted =
|
||||
dao.exists(testPermission.getUserId(), testPermission.getInstanceId(), "read");
|
||||
final boolean fakePermissionExisted =
|
||||
dao.exists(testPermission.getUserId(), testPermission.getInstanceId(), "fake");
|
||||
|
||||
assertEquals(readPermissionExisted, testPermission.getActions().contains("read"));
|
||||
assertEquals(fakePermissionExisted, testPermission.getActions().contains("fake"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenPermissionsExistsUserIdArgumentIsNull() throws Exception {
|
||||
dao.exists(null, "instance", "action");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenPermissionsExistsInstanceIdArgumentIsNull() throws Exception {
|
||||
dao.exists("user", null, "action");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowExceptionWhenPermissionsExistsActionArgumentIsNull() throws Exception {
|
||||
dao.exists("user", "instance", null);
|
||||
}
|
||||
|
||||
public static class TestDomain extends AbstractPermissionsDomain<StackPermissionsImpl> {
|
||||
public TestDomain() {
|
||||
super("stack", asList("read", "write", "use", "delete"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackPermissionsImpl doCreateInstance(
|
||||
String userId, String instanceId, List<String> allowedActions) {
|
||||
return new StackPermissionsImpl(userId, instanceId, allowedActions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,95 +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.workspace.server.stack;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.workspace.server.event.StackPersistedEvent;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link StackCreatorPermissionsProvider}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class StackCreatorPermissionsProviderTest {
|
||||
|
||||
@Mock private EventService eventService;
|
||||
|
||||
@Mock private PermissionsManager permManager;
|
||||
|
||||
@InjectMocks private StackCreatorPermissionsProvider permProvider;
|
||||
|
||||
@AfterMethod
|
||||
public void resetContext() {
|
||||
EnvironmentContext.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddPermissions() throws Exception {
|
||||
final EnvironmentContext ctx = new EnvironmentContext();
|
||||
ctx.setSubject(new SubjectImpl("test-user-name", "test-user-id", "test-token", false));
|
||||
EnvironmentContext.setCurrent(ctx);
|
||||
final StackImpl stack = createStack();
|
||||
|
||||
permProvider.onEvent(new StackPersistedEvent(stack));
|
||||
|
||||
final ArgumentCaptor<StackPermissionsImpl> captor =
|
||||
ArgumentCaptor.forClass(StackPermissionsImpl.class);
|
||||
verify(permManager).storePermission(captor.capture());
|
||||
final StackPermissionsImpl perm = captor.getValue();
|
||||
assertEquals(perm.getInstanceId(), stack.getId());
|
||||
assertEquals(perm.getUserId(), "test-user-id");
|
||||
assertEquals(perm.getDomainId(), StackDomain.DOMAIN_ID);
|
||||
assertEquals(perm.getActions(), StackDomain.getActions());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotAddPermissionsIfThereIsNoUserInEnvironmentContext() throws Exception {
|
||||
permProvider.onEvent(new StackPersistedEvent(createStack()));
|
||||
|
||||
verify(permManager, never()).storePermission(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSubscribe() {
|
||||
permProvider.subscribe();
|
||||
|
||||
verify(eventService).subscribe(permProvider, StackPersistedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUnsubscribe() {
|
||||
permProvider.unsubscribe();
|
||||
|
||||
verify(eventService).unsubscribe(permProvider, StackPersistedEvent.class);
|
||||
}
|
||||
|
||||
private static StackImpl createStack() {
|
||||
return StackImpl.builder().setId("test").setName("test").setCreator("test").build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
--
|
||||
-- Copyright (c) 2012-2019 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
|
||||
--
|
||||
|
||||
DROP TABLE che_stack_permissions_actions;
|
||||
DROP TABLE che_stack_permissions;
|
||||
|
|
@ -1,50 +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.selenium.core.constant;
|
||||
|
||||
/** @author Ann Shumilova */
|
||||
public enum TestStacksConstants {
|
||||
ANDROID("android-default", "Android"),
|
||||
JAVA("java-default", "Java"),
|
||||
JAVA_MYSQL("java-mysql", "Java-MySQL"),
|
||||
BLANK("blank-default", "Blank"),
|
||||
BITNAMI_CODEIGNITER("bitnami-codeigniter", "Bitnami Codeigniter"),
|
||||
BITNAMI_SYMFONY("bitnami-symfony", "Bitnami Symfony"),
|
||||
BITNAMI_PLAY_FOR_JAVA("bitnami-java-play", "Bitnami Play for Java"),
|
||||
BITNAMI_RAILS("bitnami-rails", "Bitnami Rails"),
|
||||
BITNAMI_EXPRESS("bitnami-express", "Bitnami Express"),
|
||||
BITNAMI_LARAVEL("bitnami-laravel", "Bitnami Laravel"),
|
||||
BITNAMI_SWIFT("bitnami-swift", "Bitnami Swift"),
|
||||
CPP("cpp-default", "C++"),
|
||||
DOTNET("dotnet-default", ".NET"),
|
||||
ECLIPSE_CHE("che-in-che", "Eclipse Che"),
|
||||
NODE("node-default", "Node"),
|
||||
PHP("php-default", "PHP"),
|
||||
PYTHON("python-default", "Python"),
|
||||
RAILS("rails-default", "Rails");
|
||||
|
||||
private final String id;
|
||||
private final String name;
|
||||
|
||||
TestStacksConstants(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ import java.util.List;
|
|||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspaceProvider;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
|
||||
/**
|
||||
|
|
@ -36,27 +37,24 @@ public class CreateWorkspaceHelper {
|
|||
@Inject private DefaultTestUser defaultTestUser;
|
||||
@Inject private TestWorkspaceProvider testWorkspaceProvider;
|
||||
|
||||
public TestWorkspace createWorkspaceFromStackWithProject(
|
||||
NewWorkspace.Stack stack, String workspaceName, String projectName) {
|
||||
return createWorkspaceFromStack(stack, workspaceName, ImmutableList.of(projectName), null);
|
||||
public TestWorkspace createWorkspaceFromDevfileWithProject(
|
||||
Devfile devfile, String workspaceName, String projectName) {
|
||||
return createWorkspaceFromStack(devfile, workspaceName, ImmutableList.of(projectName), null);
|
||||
}
|
||||
|
||||
public TestWorkspace createWorkspaceFromStackWithoutProject(
|
||||
NewWorkspace.Stack stack, String workspaceName) {
|
||||
return createWorkspaceFromStack(stack, workspaceName, Collections.emptyList(), null);
|
||||
public TestWorkspace createWorkspaceFromDevfileWithoutProject(
|
||||
Devfile devfile, String workspaceName) {
|
||||
return createWorkspaceFromStack(devfile, workspaceName, Collections.emptyList(), null);
|
||||
}
|
||||
|
||||
public TestWorkspace createWorkspaceFromStackWithProjects(
|
||||
NewWorkspace.Stack stack, String workspaceName, List<String> projectNames) {
|
||||
return createWorkspaceFromStack(stack, workspaceName, projectNames, null);
|
||||
Devfile devfile, String workspaceName, List<String> projectNames) {
|
||||
return createWorkspaceFromStack(devfile, workspaceName, projectNames, null);
|
||||
}
|
||||
|
||||
public TestWorkspace createWorkspaceFromStack(
|
||||
NewWorkspace.Stack stack,
|
||||
String workspaceName,
|
||||
List<String> projectNames,
|
||||
Double machineRam) {
|
||||
prepareWorkspace(stack, workspaceName, machineRam);
|
||||
Devfile devfile, String workspaceName, List<String> projectNames, Double machineRam) {
|
||||
prepareWorkspace(devfile, workspaceName, machineRam);
|
||||
|
||||
projectSourcePage.clickOnAddOrImportProjectButton();
|
||||
projectNames.forEach(projectSourcePage::selectSample);
|
||||
|
|
@ -67,14 +65,14 @@ public class CreateWorkspaceHelper {
|
|||
return testWorkspaceProvider.getWorkspace(workspaceName, defaultTestUser);
|
||||
}
|
||||
|
||||
private void prepareWorkspace(NewWorkspace.Stack stack, String workspaceName, Double machineRam) {
|
||||
private void prepareWorkspace(Devfile devfile, String workspaceName, Double machineRam) {
|
||||
dashboard.waitDashboardToolbarTitle();
|
||||
|
||||
dashboard.selectWorkspacesItemOnDashboard();
|
||||
workspaces.clickOnAddWorkspaceBtn();
|
||||
|
||||
newWorkspace.waitToolbar();
|
||||
newWorkspace.selectStack(stack);
|
||||
newWorkspace.selectDevfile(devfile);
|
||||
newWorkspace.typeWorkspaceName(workspaceName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ import static java.util.Arrays.asList;
|
|||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.WIDGET_TIMEOUT_SEC;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.BOTTOM_CREATE_BUTTON_XPATH;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.DEVFILE_ROW_XPATH;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.ERROR_MESSAGE;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.ORGANIZATIONS_LIST_ID;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.STACK_ROW_XPATH;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.TOOLBAR_TITLE_ID;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.TOP_CREATE_BUTTON_XPATH;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Locators.TOP_DROPDOWN_BUTTON_XPATH;
|
||||
|
|
@ -73,7 +73,7 @@ public class NewWorkspace {
|
|||
String WORKSPACE_NAME_INPUT = "workspace-name-input";
|
||||
String ERROR_MESSAGE = "new-workspace-error-message";
|
||||
String TOOLBAR_TITLE_ID = "New_Workspace";
|
||||
String STACK_ROW_XPATH = "//div[@data-devfile-id='%s']";
|
||||
String DEVFILE_ROW_XPATH = "//div[@data-devfile-id='%s']";
|
||||
String MACHINE_NAME =
|
||||
"//span[contains(@class,'ram-settings-machine-item-item-name') and text()='%s']";
|
||||
String ORGANIZATIONS_LIST_ID = "namespace-selector";
|
||||
|
|
@ -85,7 +85,7 @@ public class NewWorkspace {
|
|||
String BOTTOM_CREATE_BUTTON_XPATH = "//che-button-save-flat/button[@name='saveButton']";
|
||||
}
|
||||
|
||||
public enum Stack {
|
||||
public enum Devfile {
|
||||
APACHE_CAMEL("Apache Camel based projects on Che 7"),
|
||||
DOT_NET(".NET Core with Theia IDE"),
|
||||
GO("Go with Theia IDE"),
|
||||
|
|
@ -96,15 +96,15 @@ public class NewWorkspace {
|
|||
// wsnext-helloworld-openshift
|
||||
private final String id;
|
||||
|
||||
Stack(String id) {
|
||||
Devfile(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static Stack getById(String id) {
|
||||
Optional<Stack> first =
|
||||
asList(values()).stream().filter(stack -> stack.getId().equals(id)).findFirst();
|
||||
public static Devfile getById(String id) {
|
||||
Optional<Devfile> first =
|
||||
asList(values()).stream().filter(devfile -> devfile.getId().equals(id)).findFirst();
|
||||
first.orElseThrow(
|
||||
() -> new RuntimeException(String.format("Stack with id '%s' not found.", id)));
|
||||
() -> new RuntimeException(String.format("Devfile with id '%s' not found.", id)));
|
||||
return first.get();
|
||||
}
|
||||
|
||||
|
|
@ -176,14 +176,16 @@ public class NewWorkspace {
|
|||
seleniumWebDriverHelper.waitVisibility(By.id(TOOLBAR_TITLE_ID), timeout);
|
||||
}
|
||||
|
||||
public boolean isStackVisible(Stack stack) {
|
||||
return seleniumWebDriver.findElements(By.xpath(format(STACK_ROW_XPATH, stack.getId()))).size()
|
||||
public boolean isDevfileVisible(Devfile devfile) {
|
||||
return seleniumWebDriver
|
||||
.findElements(By.xpath(format(DEVFILE_ROW_XPATH, devfile.getId())))
|
||||
.size()
|
||||
> 0;
|
||||
}
|
||||
|
||||
public void selectStack(Stack stack) {
|
||||
waitStacks(asList(stack));
|
||||
seleniumWebDriverHelper.waitAndClick(By.xpath(format(STACK_ROW_XPATH, stack.getId())));
|
||||
public void selectDevfile(Devfile devfile) {
|
||||
waitDevfiles(asList(devfile));
|
||||
seleniumWebDriverHelper.waitAndClick(By.xpath(format(DEVFILE_ROW_XPATH, devfile.getId())));
|
||||
}
|
||||
|
||||
public boolean isCreateWorkspaceButtonEnabled() {
|
||||
|
|
@ -287,69 +289,70 @@ public class NewWorkspace {
|
|||
waitPageLoad(DEFAULT_TIMEOUT);
|
||||
}
|
||||
|
||||
public List<Stack> getAvailableStacks() {
|
||||
public List<Devfile> getAvailableDevfiles() {
|
||||
return seleniumWebDriverHelper
|
||||
.waitPresenceOfAllElements(By.xpath("//div[@data-devfile-id]"))
|
||||
.stream()
|
||||
.map(webElement -> Stack.getById(webElement.getAttribute("data-devfile-id")))
|
||||
.map(webElement -> Devfile.getById(webElement.getAttribute("data-devfile-id")))
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
public void waitStackSelected(Stack stack) {
|
||||
String selectedStackXpath =
|
||||
public void waitDevfileSelected(Devfile devfile) {
|
||||
String selectedDevfileXpath =
|
||||
format(
|
||||
"//div[@data-devfile-id='%s' and contains(@class, 'devfile-selector-item-selected')]",
|
||||
stack.getId());
|
||||
seleniumWebDriverHelper.waitVisibility(By.xpath(selectedStackXpath));
|
||||
devfile.getId());
|
||||
seleniumWebDriverHelper.waitVisibility(By.xpath(selectedDevfileXpath));
|
||||
}
|
||||
|
||||
public List<Stack> getVisibleStacks() {
|
||||
public List<Devfile> getVisibleDevfiles() {
|
||||
return seleniumWebDriverHelper
|
||||
.waitPresenceOfAllElements(By.xpath("//div[@data-devfile-id]"))
|
||||
.stream()
|
||||
.filter(seleniumWebDriverHelper::isVisible)
|
||||
.map(webElement -> Stack.getById(webElement.getAttribute("data-devfile-id")))
|
||||
.map(webElement -> Devfile.getById(webElement.getAttribute("data-devfile-id")))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void waitVisibleStacks(List<Stack> expectedVisibleStacks) {
|
||||
public void waitVisibleDevfiles(List<Devfile> expectedVisibleDevfiles) {
|
||||
webDriverWaitFactory
|
||||
.get()
|
||||
.until(
|
||||
(ExpectedCondition<Boolean>)
|
||||
driver -> getVisibleStacks().equals(expectedVisibleStacks));
|
||||
driver -> getVisibleDevfiles().equals(expectedVisibleDevfiles));
|
||||
}
|
||||
|
||||
public void waitStacks(List<Stack> expectedStacks) {
|
||||
expectedStacks.forEach(
|
||||
stack ->
|
||||
public void waitDevfiles(List<Devfile> expectedDevfiles) {
|
||||
expectedDevfiles.forEach(
|
||||
devfile ->
|
||||
seleniumWebDriverHelper.waitPresence(
|
||||
By.xpath(format("//div[@data-devfile-id='%s']", stack.getId()))));
|
||||
By.xpath(format("//div[@data-devfile-id='%s']", devfile.getId()))));
|
||||
}
|
||||
|
||||
public void waitStacksCount(int expectedCount) {
|
||||
public void waitDevfilesCount(int expectedCount) {
|
||||
webDriverWaitFactory
|
||||
.get()
|
||||
.until((ExpectedCondition<Boolean>) driver -> expectedCount == getAvailableStacksCount());
|
||||
.until((ExpectedCondition<Boolean>) driver -> expectedCount == getAvailableDevfilesCount());
|
||||
}
|
||||
|
||||
public int getAvailableStacksCount() {
|
||||
return getAvailableStacks().size();
|
||||
public int getAvailableDevfilesCount() {
|
||||
return getAvailableDevfiles().size();
|
||||
}
|
||||
|
||||
public void waitStacksNotPresent(List<Stack> stacksIdForChecking) {
|
||||
stacksIdForChecking.forEach(
|
||||
stack ->
|
||||
public void waitDevfilesNotPresent(List<Devfile> devfilesIdForChecking) {
|
||||
devfilesIdForChecking.forEach(
|
||||
devfile ->
|
||||
webDriverWaitFactory
|
||||
.get()
|
||||
.until(
|
||||
(ExpectedCondition<Boolean>) driver -> !getAvailableStacks().contains(stack)));
|
||||
(ExpectedCondition<Boolean>)
|
||||
driver -> !getAvailableDevfiles().contains(devfile)));
|
||||
}
|
||||
|
||||
public void waitStacksOrder(List<Stack> expectedOrder) {
|
||||
public void waitDevfilesOrder(List<Devfile> expectedOrder) {
|
||||
webDriverWaitFactory
|
||||
.get()
|
||||
.until((ExpectedCondition<Boolean>) driver -> expectedOrder.equals(getAvailableStacks()));
|
||||
.until((ExpectedCondition<Boolean>) driver -> expectedOrder.equals(getAvailableDevfiles()));
|
||||
}
|
||||
|
||||
public void clickNameButton() {
|
||||
|
|
|
|||
|
|
@ -1,68 +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.selenium.pageobject.dashboard.stacks;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
|
||||
@Singleton
|
||||
public class StackDetails {
|
||||
private final SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
|
||||
@Inject
|
||||
public StackDetails(
|
||||
SeleniumWebDriver seleniumWebDriver, SeleniumWebDriverHelper seleniumWebDriverHelper) {
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
||||
private interface Locators {
|
||||
String TOOLBAR_XPATH = "//*[@name='stackForm']";
|
||||
String TOOLBAR_WITH_STACK_NAME_XPATH_PATTERN = "//div[@che-title='%s']";
|
||||
String NEW_STACK_NAME = "deskname";
|
||||
String SAVE_CHANGES_BUTTON_NAME = "saveButton";
|
||||
String ALL_STACKS_BUTTON_XPATH = "//a[@title='All stacks']";
|
||||
}
|
||||
|
||||
@FindBy(name = Locators.NEW_STACK_NAME)
|
||||
WebElement stackNameField;
|
||||
|
||||
public void waitToolbar() {
|
||||
seleniumWebDriverHelper.waitVisibility(By.xpath(Locators.TOOLBAR_XPATH));
|
||||
}
|
||||
|
||||
public void waitToolbarWithStackName(String stackName) {
|
||||
seleniumWebDriverHelper.waitVisibility(
|
||||
By.xpath(format(Locators.TOOLBAR_WITH_STACK_NAME_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public void setStackName(String stackName) {
|
||||
seleniumWebDriverHelper.waitAndClick(stackNameField);
|
||||
seleniumWebDriverHelper.setValue(stackNameField, stackName);
|
||||
}
|
||||
|
||||
public void clickOnSaveChangesButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(By.name(Locators.SAVE_CHANGES_BUTTON_NAME));
|
||||
}
|
||||
|
||||
public void clickOnAllStacksButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(By.xpath(Locators.ALL_STACKS_BUTTON_XPATH));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,226 +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.selenium.pageobject.dashboard.stacks;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.utils.WaitUtils;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
|
||||
@Singleton
|
||||
public class Stacks {
|
||||
private final SeleniumWebDriver seleniumWebDriver;
|
||||
private final SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
|
||||
@Inject
|
||||
public Stacks(
|
||||
SeleniumWebDriver seleniumWebDriver, SeleniumWebDriverHelper seleniumWebDriverHelper) {
|
||||
this.seleniumWebDriver = seleniumWebDriver;
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
||||
private interface Locators {
|
||||
String TOOLBAR_ID = "Stacks";
|
||||
String DOCUMENTATION_LINK_XPATH = "//div[@che-link-title='Learn more.']/a";
|
||||
String ADD_STACK_BUTTON_ID = "import-item-button";
|
||||
String BUILD_STACK_FROM_RECIPE_BUTTON_ID = "import-item-button";
|
||||
String DELETE_STACK_BUTTON_ID = "delete-item-button";
|
||||
String DELETE_DIALOG_BUTTON_ID = "ok-dialog-button";
|
||||
String SEARCH_STACK_FIELD_XPATH = "//input[@ng-placeholder='Search']";
|
||||
String STACKS_LIST_HEADERS_XPATH = "//div[@che-column-title]";
|
||||
String SORT_STACKS_BY_NAME_ID = "sort-stacks-by-name";
|
||||
String BULK_CHECKBOX_XPATH = "//md-checkbox[@aria-label='Stack list']";
|
||||
String NO_STACKS_FOUND_XPATH = "//span[text()='No stacks found.']";
|
||||
String STACK_ITEM_XPATH = "//div[contains(@class, 'stack-item-name')]";
|
||||
String STACK_ITEM_CHECKBOX_XPATH_PATTERN = "//div[@id='stack-name-%s']//md-checkbox";
|
||||
String STACK_ITEM_NAME_XPATH_PATTERN = "//div[@id='stack-name-%s']";
|
||||
String STACK_ITEM_NAME_CONTAINS_XPATH_PATTERN = "//div[contains(@id,'stack-name-%s')]";
|
||||
String STACK_ITEM_COMPONENTS_XPATH_PATTERN =
|
||||
"//div[@id='stack-name-%s']//div[contains(@class,'stack-item-components')]";
|
||||
String STACK_ITEM_DESCRIPTION_XPATH_PATTERN =
|
||||
"//div[@id='stack-name-%s']//div[contains(@class,'stack-item-description')]";
|
||||
String STACK_ITEM_DELETE_BUTTON_XPATH_PATTERN =
|
||||
"//div[@id='stack-name-%s']//a[@uib-tooltip='Delete Stack']";
|
||||
String DUPLICATE_STACK_BUTTON_XPATH_PATTERN =
|
||||
"//div[@id='stack-name-%s']//a[@uib-tooltip='Duplicate stack']";
|
||||
String BUILD_STACK_FROM_RECIPE_DIALOG_XPATH = "//*[@title='Build stack from recipe']";
|
||||
}
|
||||
|
||||
@FindBy(id = Locators.TOOLBAR_ID)
|
||||
WebElement toolbar;
|
||||
|
||||
@FindBy(id = Locators.ADD_STACK_BUTTON_ID)
|
||||
WebElement addWorkspaceBtn;
|
||||
|
||||
@FindBy(id = Locators.DELETE_STACK_BUTTON_ID)
|
||||
WebElement deleteStackButton;
|
||||
|
||||
@FindBy(xpath = Locators.BULK_CHECKBOX_XPATH)
|
||||
WebElement bulkCheckbox;
|
||||
|
||||
@FindBy(id = Locators.BUILD_STACK_FROM_RECIPE_BUTTON_ID)
|
||||
WebElement buildStackFromRecipeButton;
|
||||
|
||||
@FindBy(id = Locators.DELETE_DIALOG_BUTTON_ID)
|
||||
WebElement deleteDialogBtn;
|
||||
|
||||
@FindBy(xpath = Locators.SEARCH_STACK_FIELD_XPATH)
|
||||
WebElement searchStackField;
|
||||
|
||||
public void waitToolbarTitleName() {
|
||||
seleniumWebDriverHelper.waitVisibility(toolbar);
|
||||
}
|
||||
|
||||
public void waitAddStackButton() {
|
||||
seleniumWebDriverHelper.waitVisibility(addWorkspaceBtn);
|
||||
}
|
||||
|
||||
public void clickOnAddStackButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(addWorkspaceBtn);
|
||||
}
|
||||
|
||||
public void waitBuildStackFromRecipeButton() {
|
||||
seleniumWebDriverHelper.waitVisibility(buildStackFromRecipeButton);
|
||||
}
|
||||
|
||||
public void clickOnBuildStackFromRecipeButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(buildStackFromRecipeButton);
|
||||
}
|
||||
|
||||
public void waitBuildStackFromRecipeDialog() {
|
||||
seleniumWebDriverHelper.waitVisibility(By.xpath(Locators.BUILD_STACK_FROM_RECIPE_DIALOG_XPATH));
|
||||
}
|
||||
|
||||
public void selectAllStacksByBulk() {
|
||||
seleniumWebDriverHelper.waitAndClick(bulkCheckbox);
|
||||
}
|
||||
|
||||
public void selectStackByCheckbox(String stackName) {
|
||||
seleniumWebDriverHelper.waitAndClick(
|
||||
By.xpath(String.format(Locators.STACK_ITEM_CHECKBOX_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public boolean isStackChecked(String workspaceName) {
|
||||
String attrValue =
|
||||
seleniumWebDriverHelper.waitVisibilityAndGetAttribute(
|
||||
By.xpath(format(Locators.STACK_ITEM_CHECKBOX_XPATH_PATTERN, workspaceName)),
|
||||
"aria-checked");
|
||||
|
||||
return Boolean.parseBoolean(attrValue);
|
||||
}
|
||||
|
||||
public void openStackDetails(String stackName) {
|
||||
seleniumWebDriverHelper.waitAndClick(
|
||||
By.xpath(String.format(Locators.STACK_ITEM_NAME_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public void waitStackItem(String stackName) {
|
||||
seleniumWebDriverHelper.waitVisibility(
|
||||
By.xpath(format(Locators.STACK_ITEM_NAME_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public Boolean isStackItemExisted(String stackName) {
|
||||
return seleniumWebDriverHelper.isVisible(
|
||||
By.xpath(format(Locators.STACK_ITEM_NAME_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public Boolean isDuplicatedStackExisted(String stackName) {
|
||||
return seleniumWebDriverHelper.isVisible(
|
||||
By.xpath(format(Locators.STACK_ITEM_NAME_CONTAINS_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public String getStackDescription(String stackName) {
|
||||
return seleniumWebDriverHelper.waitVisibilityAndGetText(
|
||||
By.xpath(format(Locators.STACK_ITEM_DESCRIPTION_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public String getStackComponents(String stackName) {
|
||||
return seleniumWebDriverHelper.waitVisibilityAndGetText(
|
||||
By.xpath(format(Locators.STACK_ITEM_COMPONENTS_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public void clickOnDeleteActionButton(String stackName) {
|
||||
seleniumWebDriverHelper.waitAndClick(
|
||||
By.xpath(format(Locators.STACK_ITEM_DELETE_BUTTON_XPATH_PATTERN, stackName)));
|
||||
}
|
||||
|
||||
public void clickOnDuplicateStackButton(String stackName) {
|
||||
seleniumWebDriverHelper.waitAndClick(
|
||||
By.xpath(format(Locators.DUPLICATE_STACK_BUTTON_XPATH_PATTERN, stackName)));
|
||||
WaitUtils.sleepQuietly(1);
|
||||
}
|
||||
|
||||
public Boolean isDeleteStackButtonEnabled() {
|
||||
return seleniumWebDriverHelper.isVisible(deleteStackButton);
|
||||
}
|
||||
|
||||
public void clickOnDeleteStackButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(deleteStackButton);
|
||||
}
|
||||
|
||||
public void clickOnDeleteDialogButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(deleteDialogBtn);
|
||||
}
|
||||
|
||||
public void waitFilterStacksField() {
|
||||
seleniumWebDriverHelper.waitVisibility(searchStackField);
|
||||
}
|
||||
|
||||
public void typeToSearchInput(String value) {
|
||||
seleniumWebDriverHelper.setValue(searchStackField, value);
|
||||
}
|
||||
|
||||
public void waitNoStacksFound() {
|
||||
seleniumWebDriverHelper.waitVisibility(By.xpath(Locators.NO_STACKS_FOUND_XPATH));
|
||||
}
|
||||
|
||||
public ArrayList<String> getStacksListHeaders() {
|
||||
ArrayList<String> titles = new ArrayList<>();
|
||||
List<WebElement> headers =
|
||||
seleniumWebDriver.findElements(By.xpath(Locators.STACKS_LIST_HEADERS_XPATH));
|
||||
headers.forEach(
|
||||
header -> {
|
||||
titles.add(header.getText());
|
||||
});
|
||||
|
||||
return titles;
|
||||
}
|
||||
|
||||
public ArrayList<String> getStacksNamesList() {
|
||||
ArrayList<String> stacksNames = new ArrayList<>();
|
||||
List<WebElement> names = seleniumWebDriver.findElements(By.xpath(Locators.STACK_ITEM_XPATH));
|
||||
names.forEach(
|
||||
name -> {
|
||||
stacksNames.add(name.getText());
|
||||
});
|
||||
|
||||
return stacksNames;
|
||||
}
|
||||
|
||||
public void clickOnSortStacksByNameButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(By.id(Locators.SORT_STACKS_BY_NAME_ID));
|
||||
}
|
||||
|
||||
public void waitDocumentationLink() {
|
||||
seleniumWebDriverHelper.waitVisibility(By.xpath(Locators.DOCUMENTATION_LINK_XPATH));
|
||||
}
|
||||
}
|
||||
|
|
@ -302,7 +302,7 @@ public class Workspaces {
|
|||
}
|
||||
|
||||
public void clickOnStackButton() {
|
||||
seleniumWebDriverHelper.waitAndClick(By.xpath("//div[@che-column-title='Stack']/div"));
|
||||
seleniumWebDriverHelper.waitAndClick(By.xpath("//div[@che-column-title='Devfile']/div"));
|
||||
}
|
||||
|
||||
public void clickOnWorkspaceStopStartButton(String workspaceName) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import org.eclipse.che.selenium.core.workspace.TestWorkspaceProvider;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NavigationBar;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceProjects;
|
||||
|
|
@ -78,8 +78,8 @@ public class CreateAndDeleteProjectsTest {
|
|||
newWorkspace.waitToolbar();
|
||||
dashboardWindow = seleniumWebDriver.getWindowHandle();
|
||||
|
||||
// we are selecting 'Java' stack from the 'All Stack' tab for compatibility with OSIO
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
// we are selecting 'Java' stack from the 'All Devfile' tab for compatibility with OSIO
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE);
|
||||
projectSourcePage.waitCreatedProjectButton(CONSOLE_JAVA_SIMPLE);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import org.eclipse.che.selenium.pageobject.Loader;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.DashboardFactories;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.factories.CreateFactoryPage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.factories.FactoryDetails;
|
||||
|
|
@ -377,8 +377,8 @@ public class CreateFactoryTest {
|
|||
newWorkspace.waitToolbar();
|
||||
loader.waitOnClosed();
|
||||
|
||||
// we are selecting 'Java' stack from the 'All Stack' tab for compatibility with OSIO
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
// we are selecting 'Java' stack from the 'All Devfile' tab for compatibility with OSIO
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.typeWorkspaceName(workspaceName);
|
||||
|
||||
projectSourcePage.clickOnAddOrImportProjectButton();
|
||||
|
|
@ -403,8 +403,8 @@ public class CreateFactoryTest {
|
|||
newWorkspace.waitToolbar();
|
||||
loader.waitOnClosed();
|
||||
|
||||
// we are selecting 'Java' stack from the 'All Stack' tab for compatibility with OSIO
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
// we are selecting 'Java' stack from the 'All Devfile' tab for compatibility with OSIO
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.typeWorkspaceName(workspaceName);
|
||||
|
||||
newWorkspace.clickOnCreateButtonAndEditWorkspace();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import com.google.inject.Inject;
|
|||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
|
@ -80,7 +80,7 @@ public class CreateWorkspaceTest {
|
|||
@Test
|
||||
public void checkProjectSourcePage() {
|
||||
// add a project from the 'console-java-simple' sample
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
projectSourcePage.waitOpened();
|
||||
projectSourcePage.waitCreatedProjectButton(projectName);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import org.eclipse.che.selenium.core.workspace.TestWorkspace;
|
|||
import org.eclipse.che.selenium.core.workspace.TestWorkspaceProvider;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.eclipse.che.selenium.pageobject.theia.TheiaIde;
|
||||
|
|
@ -77,8 +77,8 @@ public class ImportMavenProjectFromGitTest {
|
|||
workspaces.clickOnAddWorkspaceBtn();
|
||||
newWorkspace.waitToolbar();
|
||||
|
||||
// we are selecting 'Java' stack from the 'All Stack' tab for compatibility with OSIO
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
// we are selecting 'Java' stack from the 'All Devfile' tab for compatibility with OSIO
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE);
|
||||
|
||||
projectSourcePage.clickOnAddOrImportProjectButton();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import org.eclipse.che.selenium.core.workspace.TestWorkspaceProvider;
|
|||
import org.eclipse.che.selenium.pageobject.Ide;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.eclipse.che.selenium.pageobject.theia.TheiaIde;
|
||||
|
|
@ -97,8 +97,8 @@ public class ImportProjectFromGitHubTest {
|
|||
dashboard.selectWorkspacesItemOnDashboard();
|
||||
workspaces.clickOnAddWorkspaceBtn();
|
||||
newWorkspace.waitToolbar();
|
||||
// we are selecting 'Java' stack from the 'All Stack' tab for compatibility with OSIO
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
// we are selecting 'Java' stack from the 'All Devfile' tab for compatibility with OSIO
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE);
|
||||
|
||||
projectSourcePage.clickOnAddOrImportProjectButton();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import org.eclipse.che.selenium.core.user.TestUser;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.CheMultiuserAdminDashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NavigationBar;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.organization.OrganizationListPage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.organization.OrganizationPage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails;
|
||||
|
|
@ -173,7 +173,7 @@ public class AddWorkspaceToOrganizationTest {
|
|||
newWorkspace.waitToolbar();
|
||||
newWorkspace.openOrganizationsList();
|
||||
newWorkspace.selectOrganizationFromList(organizationName);
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.typeWorkspaceName(workspaceName);
|
||||
newWorkspace.clickOnCreateButtonAndEditWorkspace();
|
||||
workspaceDetails.waitToolbarTitleName(workspaceName);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import org.eclipse.che.selenium.pageobject.ProjectExplorer;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.CheMultiuserAdminDashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.CreateWorkspaceHelper;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NavigationBar;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.StateWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceOverview;
|
||||
|
|
@ -179,8 +179,8 @@ public class ShareWorkspaceMemberTest {
|
|||
}
|
||||
|
||||
private void createWorkspace(String workspaceName) {
|
||||
createWorkspaceHelper.createWorkspaceFromStackWithProject(
|
||||
Stack.JAVA_MAVEN, workspaceName, PROJECT_NAME);
|
||||
createWorkspaceHelper.createWorkspaceFromDevfileWithProject(
|
||||
Devfile.JAVA_MAVEN, workspaceName, PROJECT_NAME);
|
||||
|
||||
ide.switchToIdeAndWaitWorkspaceIsReadyToUse();
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import org.eclipse.che.selenium.core.user.TestUser;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.CheMultiuserAdminDashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NavigationBar;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceShare;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
|
|
@ -157,7 +157,7 @@ public class ShareWorkspaceOwnerTest {
|
|||
newWorkspace.waitToolbar();
|
||||
newWorkspace.openOrganizationsList();
|
||||
newWorkspace.selectOrganizationFromList(organizationName);
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.typeWorkspaceName(workspaceName);
|
||||
newWorkspace.clickOnCreateButtonAndEditWorkspace();
|
||||
workspaceDetails.waitToolbarTitleName(workspaceName);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import org.eclipse.che.selenium.core.workspace.TestWorkspace;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.DocumentationPage;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceConfig;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceOverview;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceProjects;
|
||||
|
|
@ -341,7 +341,7 @@ public class WorkspacesListTest {
|
|||
workspaces.clickOnAddWorkspaceBtn();
|
||||
newWorkspace.waitToolbar();
|
||||
newWorkspace.typeWorkspaceName(NEWEST_CREATED_WORKSPACE_NAME);
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.clickOnCreateButtonAndEditWorkspace();
|
||||
workspaceOverview.checkNameWorkspace(NEWEST_CREATED_WORKSPACE_NAME);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.AddOrImportForm;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceOverview;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.testng.annotations.Test;
|
||||
|
|
@ -115,9 +115,9 @@ public class WorkspaceDetailsOverviewTest {
|
|||
newWorkspace.waitPageLoad();
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE_NAME);
|
||||
|
||||
selectStackAndCheckWorkspaceName(Stack.APACHE_CAMEL);
|
||||
selectDevfileAndCheckWorkspaceName(Devfile.APACHE_CAMEL);
|
||||
|
||||
selectStackAndCheckWorkspaceName(Stack.JAVA_GRADLE);
|
||||
selectDevfileAndCheckWorkspaceName(Devfile.JAVA_GRADLE);
|
||||
|
||||
// create workspace
|
||||
addOrImportForm.clickOnAddOrImportProjectButton();
|
||||
|
|
@ -176,9 +176,9 @@ public class WorkspaceDetailsOverviewTest {
|
|||
workspaceOverview.waitExportWorkspaceFormClosed();
|
||||
}
|
||||
|
||||
private void selectStackAndCheckWorkspaceName(NewWorkspace.Stack stack) {
|
||||
newWorkspace.selectStack(stack);
|
||||
newWorkspace.waitStackSelected(stack);
|
||||
private void selectDevfileAndCheckWorkspaceName(Devfile devfile) {
|
||||
newWorkspace.selectDevfile(devfile);
|
||||
newWorkspace.waitDevfileSelected(devfile);
|
||||
newWorkspace.waitWorkspaceNameFieldValue(WORKSPACE_NAME);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
|||
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.AuthorizeOpenShiftAccessPage;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.OpenShiftLoginPage;
|
||||
|
|
@ -135,7 +135,7 @@ public class LoginExistedUserWithOpenShiftOAuthTest {
|
|||
workspaces.clickOnAddWorkspaceBtn();
|
||||
newWorkspace.waitToolbar();
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE_NAME);
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.clickOnCreateButtonAndOpenInIDE();
|
||||
|
||||
// switch to the IDE and wait for workspace is ready to use
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import org.eclipse.che.selenium.core.user.TestUser;
|
|||
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.AuthorizeOpenShiftAccessPage;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.OpenShiftLoginPage;
|
||||
|
|
@ -121,7 +121,7 @@ public class LoginNewUserWithOpenShiftOAuthTest {
|
|||
workspaces.clickOnAddWorkspaceBtn();
|
||||
newWorkspace.waitToolbar();
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE_NAME);
|
||||
newWorkspace.selectStack(Stack.JAVA_MAVEN);
|
||||
newWorkspace.selectDevfile(Devfile.JAVA_MAVEN);
|
||||
newWorkspace.clickOnCreateButtonAndOpenInIDE();
|
||||
|
||||
// switch to the IDE and wait for workspace is ready to use
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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.selenium.theia;
|
||||
|
||||
import static org.eclipse.che.selenium.core.TestGroup.OPENSHIFT;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.selenium.core.client.TestWorkspaceServiceClient;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.CreateWorkspaceHelper;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.theia.TheiaIde;
|
||||
import org.eclipse.che.selenium.pageobject.theia.TheiaProjectTree;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class Che7PreviewDevfileStartTest {
|
||||
private static final String WORKSPACE_NAME = NameGenerator.generate("wksp-", 5);
|
||||
|
||||
@Inject private Dashboard dashboard;
|
||||
@Inject private TheiaIde theiaIde;
|
||||
@Inject private DefaultTestUser defaultTestUser;
|
||||
@Inject private CreateWorkspaceHelper createWorkspaceHelper;
|
||||
@Inject private TestWorkspaceServiceClient workspaceServiceClient;
|
||||
@Inject private TheiaProjectTree theiaProjectTree;
|
||||
|
||||
@AfterClass
|
||||
public void tearDown() throws Exception {
|
||||
workspaceServiceClient.delete(WORKSPACE_NAME, defaultTestUser.getName());
|
||||
}
|
||||
|
||||
@Test(groups = {OPENSHIFT})
|
||||
public void workspaceShouldBeStarted() {
|
||||
dashboard.open();
|
||||
createWorkspaceHelper.createWorkspaceFromDevfileWithoutProject(Devfile.GO, WORKSPACE_NAME);
|
||||
|
||||
theiaIde.switchToIdeFrame();
|
||||
theiaIde.waitTheiaIde();
|
||||
theiaIde.waitLoaderInvisibility();
|
||||
theiaIde.waitTheiaIde();
|
||||
theiaIde.waitTheiaIdeTopPanel();
|
||||
theiaProjectTree.waitFilesTab();
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
|||
import org.eclipse.che.selenium.pageobject.dashboard.CreateWorkspaceHelper;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Devfile;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.eclipse.che.selenium.pageobject.theia.TheiaEditor;
|
||||
import org.eclipse.che.selenium.pageobject.theia.TheiaHostedPluginSelectPathForm;
|
||||
|
|
@ -66,7 +66,7 @@ public class TheiaBuildPluginTest {
|
|||
@BeforeClass
|
||||
public void prepare() {
|
||||
dashboard.open();
|
||||
createWorkspaceHelper.createWorkspaceFromStackWithoutProject(Stack.GO, WORKSPACE_NAME);
|
||||
createWorkspaceHelper.createWorkspaceFromDevfileWithoutProject(Devfile.GO, WORKSPACE_NAME);
|
||||
|
||||
theiaIde.switchToIdeFrame();
|
||||
theiaIde.waitTheiaIde();
|
||||
|
|
|
|||
|
|
@ -31,12 +31,6 @@ public final class Constants {
|
|||
public static final String WORKSPACE_STOPPED_BY = "stopped_by";
|
||||
public static final String WORKSPACE_STOP_REASON = "stop_reason";
|
||||
|
||||
public static final String LINK_REL_CREATE_STACK = "create stack";
|
||||
public static final String LINK_REL_UPDATE_STACK = "update stack";
|
||||
public static final String LINK_REL_REMOVE_STACK = "remove stack";
|
||||
public static final String LINK_REL_GET_STACK_BY_ID = "get stack by id";
|
||||
public static final String LINK_REL_SEARCH_STACKS = "search stacks";
|
||||
|
||||
public static final String LINK_REL_GET_ICON = "get icon link";
|
||||
public static final String LINK_REL_UPLOAD_ICON = "upload icon link";
|
||||
public static final String LINK_REL_DELETE_ICON = "delete icon link";
|
||||
|
|
|
|||
|
|
@ -1,28 +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.shared.dto.stack;
|
||||
|
||||
import org.eclipse.che.api.workspace.shared.stack.StackComponent;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
/** @author Alexander Andrienko */
|
||||
@DTO
|
||||
public interface StackComponentDto extends StackComponent {
|
||||
|
||||
void setName(String name);
|
||||
|
||||
StackComponentDto withName(String name);
|
||||
|
||||
void setVersion(String version);
|
||||
|
||||
StackComponentDto withVersion(String version);
|
||||
}
|
||||
|
|
@ -1,64 +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.shared.dto.stack;
|
||||
|
||||
import java.util.List;
|
||||
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.WorkspaceConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
/** @author Alexander Andrienko */
|
||||
@DTO
|
||||
public interface StackDto extends Stack, Hyperlinks {
|
||||
|
||||
void setId(String id);
|
||||
|
||||
StackDto withId(String id);
|
||||
|
||||
void setName(String name);
|
||||
|
||||
StackDto withName(String name);
|
||||
|
||||
void setDescription(String description);
|
||||
|
||||
StackDto withDescription(String description);
|
||||
|
||||
void setScope(String scope);
|
||||
|
||||
StackDto withScope(String scope);
|
||||
|
||||
void setCreator(String creator);
|
||||
|
||||
StackDto withCreator(String creator);
|
||||
|
||||
void setTags(List<String> tags);
|
||||
|
||||
StackDto withTags(List<String> tags);
|
||||
|
||||
@Override
|
||||
WorkspaceConfigDto getWorkspaceConfig();
|
||||
|
||||
void setWorkspaceConfig(WorkspaceConfigDto workspaceConfigDto);
|
||||
|
||||
StackDto withWorkspaceConfig(WorkspaceConfigDto workspaceConfigDto);
|
||||
|
||||
@Override
|
||||
List<StackComponentDto> getComponents();
|
||||
|
||||
void setComponents(List<StackComponentDto> components);
|
||||
|
||||
StackDto withComponents(List<StackComponentDto> components);
|
||||
|
||||
StackDto withLinks(List<Link> links);
|
||||
}
|
||||
|
|
@ -1,72 +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.shared.stack;
|
||||
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Defines the interface for managing stack of technologies.
|
||||
*
|
||||
* <p>Stack is the recipe/image/snapshot which declares workspace environment with certain
|
||||
* components (technologies) and provides additional meta information for it.
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
public interface Stack {
|
||||
|
||||
/** Return the unique stack identifier. (e.g. "stack123"). */
|
||||
String getId();
|
||||
|
||||
/** Return the unique stack name. (e.g. "Ruby on Rails"). */
|
||||
String getName();
|
||||
|
||||
/** Return identifier of user who is the stack creator. */
|
||||
String getCreator();
|
||||
|
||||
/** Returns the stack description, short information about the stack. */
|
||||
@Nullable
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Return the scope of the stack.
|
||||
*
|
||||
* <p>There are two types of the scope:
|
||||
*
|
||||
* <ul>
|
||||
* <li>"general" - when the stack defines common technology (e.g.: the stack "Java")
|
||||
* <li>"advanced" - when the stack defines detailed(concrete) technology implementation (e.g:
|
||||
* the stack "Java only with JRE")
|
||||
* </ul>
|
||||
*/
|
||||
String getScope();
|
||||
|
||||
/** Return list technology tags. Tag links the stack with list Project Templates. */
|
||||
List<String> getTags();
|
||||
|
||||
/**
|
||||
* Return the {@link WorkspaceConfig} for creation workspace. This workspaceConfig can be used for
|
||||
* store machine source, list predefined commands, projects etc.
|
||||
*/
|
||||
@Nullable
|
||||
WorkspaceConfig getWorkspaceConfig();
|
||||
|
||||
/**
|
||||
* Return the list of the components that stack consist of.
|
||||
*
|
||||
* @see StackComponent
|
||||
* <p>Example: [{"name": "java", "version" : "1.8.45"}, {"name" : "maven", "version" :
|
||||
* "3.3.1"}]
|
||||
*/
|
||||
List<? extends StackComponent> getComponents();
|
||||
}
|
||||
|
|
@ -1,26 +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.shared.stack;
|
||||
|
||||
/**
|
||||
* Defines the interface that describes the stack component. It is a part of the {@link Stack}.
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
public interface StackComponent {
|
||||
|
||||
/** Returns the name of the component. The name is unique per stack. (e.g. "jdk"). */
|
||||
String getName();
|
||||
|
||||
/** Returns the version of the component. (e.g. "1.8") */
|
||||
String getVersion();
|
||||
}
|
||||
|
|
@ -1,47 +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.shared.stack;
|
||||
|
||||
/**
|
||||
* Defines the interface that describes the stack source. It is a part of the {@link Stack}
|
||||
*
|
||||
* <p>Example: "source" : { "type":"image", "origin":"codenvy/ubuntu_jdk8" }
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
public interface StackSource {
|
||||
|
||||
/**
|
||||
* Returns type for the StackSource.
|
||||
*
|
||||
* <p>There are three available types of the StackSource:
|
||||
*
|
||||
* <ul>
|
||||
* <li>"recipe"
|
||||
* <li>"image"
|
||||
* <li>"location"
|
||||
* </ul>
|
||||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* Returns origin data for the Stack Source. Origin data can be:
|
||||
*
|
||||
* <ul>
|
||||
* <li>text/plain - when the type is "recipe" (e.g. "FROM codenvy/ubuntu_jdk8"})
|
||||
* <li>image tag - when the type is "image" (e.g. "codenvy/ubuntu_jdk8")
|
||||
* <li>url - when the type is "location" (e.g.
|
||||
* "https://raw.githubusercontent.com/codenvy/dockerfiles/master/php/debian/Dockerfile")
|
||||
* </ul>
|
||||
*/
|
||||
String getOrigin();
|
||||
}
|
||||
|
|
@ -58,14 +58,6 @@
|
|||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-assistedinject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentracing</groupId>
|
||||
<artifactId>opentracing-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ import org.eclipse.che.api.core.model.workspace.devfile.Source;
|
|||
import org.eclipse.che.api.core.model.workspace.runtime.Machine;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.Server;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.shared.dto.CommandDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.MachineConfigDto;
|
||||
|
|
@ -67,9 +66,6 @@ import org.eclipse.che.api.workspace.shared.dto.devfile.EnvDto;
|
|||
import org.eclipse.che.api.workspace.shared.dto.devfile.MetadataDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.ProjectDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.SourceDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackComponentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackDto;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
|
||||
/**
|
||||
* Helps to convert to/from DTOs related to workspace.
|
||||
|
|
@ -239,38 +235,6 @@ public final class DtoConverter {
|
|||
.withAttributes(command.getAttributes());
|
||||
}
|
||||
|
||||
/** Convert {@link StackImpl} to {@link StackDto}. */
|
||||
public static StackDto asDto(Stack stack) {
|
||||
WorkspaceConfigDto workspaceConfigDto = null;
|
||||
if (stack.getWorkspaceConfig() != null) {
|
||||
workspaceConfigDto = asDto(stack.getWorkspaceConfig());
|
||||
}
|
||||
|
||||
List<StackComponentDto> componentsDto = null;
|
||||
if (stack.getComponents() != null) {
|
||||
componentsDto =
|
||||
stack
|
||||
.getComponents()
|
||||
.stream()
|
||||
.map(
|
||||
component ->
|
||||
newDto(StackComponentDto.class)
|
||||
.withName(component.getName())
|
||||
.withVersion(component.getVersion()))
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
return newDto(StackDto.class)
|
||||
.withId(stack.getId())
|
||||
.withName(stack.getName())
|
||||
.withDescription(stack.getDescription())
|
||||
.withCreator(stack.getCreator())
|
||||
.withScope(stack.getScope())
|
||||
.withTags(stack.getTags())
|
||||
.withComponents(componentsDto)
|
||||
.withWorkspaceConfig(workspaceConfigDto);
|
||||
}
|
||||
|
||||
/** Converts {@link ProjectConfig} to {@link ProjectConfigDto}. */
|
||||
public static ProjectConfigDto asDto(ProjectConfig projectCfg) {
|
||||
final ProjectConfigDto projectConfigDto =
|
||||
|
|
|
|||
|
|
@ -117,8 +117,6 @@ public class WorkspaceManager {
|
|||
public WorkspaceImpl createWorkspace(
|
||||
WorkspaceConfig config, String namespace, Map<String, String> attributes)
|
||||
throws ServerException, NotFoundException, ConflictException, ValidationException {
|
||||
TracingTags.STACK_ID.set(() -> attributes.getOrDefault("stackId", "no stack"));
|
||||
|
||||
requireNonNull(config, "Required non-null config");
|
||||
requireNonNull(namespace, "Required non-null namespace");
|
||||
validator.validateConfig(config);
|
||||
|
|
@ -157,8 +155,6 @@ public class WorkspaceManager {
|
|||
Map<String, String> attributes,
|
||||
FileContentProvider contentProvider)
|
||||
throws ServerException, NotFoundException, ConflictException, ValidationException {
|
||||
TracingTags.STACK_ID.set(() -> attributes.getOrDefault("stackId", "no stack"));
|
||||
|
||||
requireNonNull(devfile, "Required non-null devfile");
|
||||
requireNonNull(namespace, "Required non-null namespace");
|
||||
validator.validateAttributes(attributes);
|
||||
|
|
@ -347,10 +343,6 @@ public class WorkspaceManager {
|
|||
}
|
||||
|
||||
Optional<WorkspaceImpl> workspaceOpt = workspaceDao.remove(workspaceId);
|
||||
workspaceOpt.ifPresent(
|
||||
workspace ->
|
||||
TracingTags.STACK_ID.set(
|
||||
workspace.getAttributes().getOrDefault("stackId", "no stack")));
|
||||
|
||||
LOG.info("Workspace '{}' removed by user '{}'", workspaceId, sessionUserNameOrUndefined());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,7 +389,6 @@ public class WorkspaceRuntimes {
|
|||
WorkspaceImpl workspace, @Nullable String envName, Map<String, String> options)
|
||||
throws ConflictException, NotFoundException, ServerException {
|
||||
TracingTags.WORKSPACE_ID.set(workspace.getId());
|
||||
TracingTags.STACK_ID.set(() -> workspace.getAttributes().getOrDefault("stackId", "no stack"));
|
||||
|
||||
final String workspaceId = workspace.getId();
|
||||
if (isStartRefused.get()) {
|
||||
|
|
@ -469,7 +468,6 @@ public class WorkspaceRuntimes {
|
|||
throws NotFoundException, ConflictException {
|
||||
TracingTags.WORKSPACE_ID.set(workspace.getId());
|
||||
TracingTags.STOPPED_BY.set(getStoppedBy(workspace));
|
||||
TracingTags.STACK_ID.set(() -> workspace.getAttributes().getOrDefault("stackId", "no stack"));
|
||||
|
||||
String workspaceId = workspace.getId();
|
||||
WorkspaceStatus status = statuses.get(workspaceId);
|
||||
|
|
|
|||
|
|
@ -163,11 +163,7 @@ public class WorkspaceService extends Service {
|
|||
value =
|
||||
"Workspace attribute defined in 'attrName:attrValue' format. "
|
||||
+ "The first ':' is considered as attribute name and value separator",
|
||||
examples =
|
||||
@Example({
|
||||
@ExampleProperty("stackId:stack123"),
|
||||
@ExampleProperty("attrName:value-with:colon")
|
||||
}))
|
||||
examples = @Example({@ExampleProperty("attrName:value-with:colon")}))
|
||||
@QueryParam("attribute")
|
||||
List<String> attrsList,
|
||||
@ApiParam(
|
||||
|
|
@ -231,11 +227,7 @@ public class WorkspaceService extends Service {
|
|||
value =
|
||||
"Workspace attribute defined in 'attrName:attrValue' format. "
|
||||
+ "The first ':' is considered as attribute name and value separator",
|
||||
examples =
|
||||
@Example({
|
||||
@ExampleProperty("stackId:stack123"),
|
||||
@ExampleProperty("attrName:value-with:colon")
|
||||
}))
|
||||
examples = @Example({@ExampleProperty("attrName:value-with:colon")}))
|
||||
@QueryParam("attribute")
|
||||
List<String> attrsList,
|
||||
@ApiParam(
|
||||
|
|
|
|||
|
|
@ -1,33 +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.event;
|
||||
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.core.db.cascade.event.RemoveEvent;
|
||||
|
||||
/**
|
||||
* Pre-removal event of {@link StackImpl}.
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
public class BeforeStackRemovedEvent extends RemoveEvent {
|
||||
|
||||
private final StackImpl stack;
|
||||
|
||||
public BeforeStackRemovedEvent(StackImpl stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
public StackImpl getStack() {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +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.event;
|
||||
|
||||
import org.eclipse.che.api.core.notification.EventOrigin;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
import org.eclipse.che.core.db.cascade.event.PersistEvent;
|
||||
|
||||
/**
|
||||
* Published after stack instance is persisted.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@EventOrigin("stack")
|
||||
public class StackPersistedEvent extends PersistEvent {
|
||||
|
||||
private final Stack stack;
|
||||
|
||||
public StackPersistedEvent(Stack stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
public Stack getStack() {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,165 +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.jpa;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
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.api.core.ApiException;
|
||||
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.workspace.server.event.BeforeStackRemovedEvent;
|
||||
import org.eclipse.che.api.workspace.server.event.StackPersistedEvent;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
|
||||
|
||||
/**
|
||||
* JPA based implementation of {@link StackDao}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class JpaStackDao implements StackDao {
|
||||
|
||||
@Inject private Provider<EntityManager> managerProvider;
|
||||
|
||||
@Inject private EventService eventService;
|
||||
|
||||
@Override
|
||||
public void create(StackImpl stack) throws ConflictException, ServerException {
|
||||
requireNonNull(stack, "Required non-null stack");
|
||||
try {
|
||||
doCreate(stack);
|
||||
} catch (DuplicateKeyException x) {
|
||||
throw new ConflictException(
|
||||
format("Stack with id '%s' or name '%s' already exists", stack.getId(), stack.getName()));
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public StackImpl getById(String id) throws NotFoundException, ServerException {
|
||||
requireNonNull(id, "Required non-null id");
|
||||
try {
|
||||
final StackImpl stack = managerProvider.get().find(StackImpl.class, id);
|
||||
if (stack == null) {
|
||||
throw new NotFoundException(format("Stack with id '%s' doesn't exist", id));
|
||||
}
|
||||
return new StackImpl(stack);
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String id) throws ServerException {
|
||||
requireNonNull(id, "Required non-null id");
|
||||
try {
|
||||
doRemove(id);
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackImpl update(StackImpl update)
|
||||
throws NotFoundException, ServerException, ConflictException {
|
||||
requireNonNull(update, "Required non-null update");
|
||||
try {
|
||||
return new StackImpl(doUpdate(update));
|
||||
} catch (DuplicateKeyException x) {
|
||||
throw new ConflictException(format("Stack with name '%s' already exists", update.getName()));
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<StackImpl> searchStacks(
|
||||
@Nullable String user, @Nullable List<String> tags, int skipCount, int maxItems)
|
||||
throws ServerException {
|
||||
final TypedQuery<StackImpl> query;
|
||||
if (tags == null || tags.isEmpty()) {
|
||||
query = managerProvider.get().createNamedQuery("Stack.getAll", StackImpl.class);
|
||||
} else {
|
||||
query =
|
||||
managerProvider
|
||||
.get()
|
||||
.createNamedQuery("Stack.getByTags", StackImpl.class)
|
||||
.setParameter("tags", tags)
|
||||
.setParameter("tagsSize", tags.size());
|
||||
}
|
||||
try {
|
||||
return query
|
||||
.setMaxResults(maxItems)
|
||||
.setFirstResult(skipCount)
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(StackImpl::new)
|
||||
.collect(Collectors.toList());
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {RuntimeException.class, ApiException.class})
|
||||
protected void doCreate(StackImpl stack) throws ConflictException, ServerException {
|
||||
if (stack.getWorkspaceConfig() != null) {
|
||||
stack.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
EntityManager manager = managerProvider.get();
|
||||
manager.persist(stack);
|
||||
manager.flush();
|
||||
eventService.publish(new StackPersistedEvent(stack)).propagateException();
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {RuntimeException.class, ServerException.class})
|
||||
protected void doRemove(String id) throws ServerException {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
final StackImpl stack = manager.find(StackImpl.class, id);
|
||||
if (stack != null) {
|
||||
eventService.publish(new BeforeStackRemovedEvent(new StackImpl(stack))).propagateException();
|
||||
manager.remove(stack);
|
||||
manager.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected StackImpl doUpdate(StackImpl update) throws NotFoundException {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
if (manager.find(StackImpl.class, update.getId()) == null) {
|
||||
throw new NotFoundException(format("Workspace with id '%s' doesn't exist", update.getId()));
|
||||
}
|
||||
if (update.getWorkspaceConfig() != null) {
|
||||
update.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
StackImpl merged = manager.merge(update);
|
||||
manager.flush();
|
||||
return merged;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,6 @@ package org.eclipse.che.api.workspace.server.jpa;
|
|||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao.RemoveWorkspaceBeforeAccountRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
|
||||
/** @author Yevhenii Voevodin */
|
||||
|
|
@ -21,7 +20,6 @@ public class WorkspaceJpaModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(StackDao.class).to(JpaStackDao.class);
|
||||
bind(WorkspaceDao.class).to(JpaWorkspaceDao.class);
|
||||
bind(RemoveWorkspaceBeforeAccountRemovedEventSubscriber.class).asEagerSingleton();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,86 +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.model.impl.stack;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import org.eclipse.che.api.workspace.shared.stack.StackComponent;
|
||||
|
||||
/**
|
||||
* OldServer implementation of {@link StackComponent}
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
@Embeddable
|
||||
public class StackComponentImpl implements StackComponent {
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "version")
|
||||
private String version;
|
||||
|
||||
public StackComponentImpl() {}
|
||||
|
||||
public StackComponentImpl(StackComponent stackComponent) {
|
||||
this(stackComponent.getName(), stackComponent.getVersion());
|
||||
}
|
||||
|
||||
public StackComponentImpl(String name, String version) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof StackComponentImpl)) {
|
||||
return false;
|
||||
}
|
||||
StackComponentImpl another = (StackComponentImpl) obj;
|
||||
return Objects.equals(name, another.name) && Objects.equals(version, another.version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = hash * 31 + Objects.hashCode(name);
|
||||
hash = hash * 31 + Objects.hashCode(version);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StackComponentImpl{" + "name='" + name + '\'' + ", version='" + version + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,375 +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.model.impl.stack;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
import org.eclipse.che.api.workspace.shared.stack.StackComponent;
|
||||
import org.eclipse.che.api.workspace.shared.stack.StackSource;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
|
||||
/**
|
||||
* Data object for {@link Stack}.
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Entity(name = "Stack")
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "Stack.getByTags",
|
||||
query =
|
||||
"SELECT stack "
|
||||
+ "FROM Stack stack, stack.tags tag "
|
||||
+ "WHERE tag IN :tags "
|
||||
+ "GROUP BY stack.id "
|
||||
+ "HAVING COUNT(tag) = :tagsSize"),
|
||||
@NamedQuery(name = "Stack.getAll", query = "SELECT stack FROM Stack stack")
|
||||
})
|
||||
@Table(name = "stack")
|
||||
public class StackImpl implements Stack {
|
||||
|
||||
public static StackBuilder builder() {
|
||||
return new StackBuilder();
|
||||
}
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String id;
|
||||
|
||||
@Column(name = "name", unique = true, nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "description", columnDefinition = "TEXT")
|
||||
private String description;
|
||||
|
||||
@Column(name = "scope")
|
||||
private String scope;
|
||||
|
||||
@Column(name = "creator")
|
||||
private String creator;
|
||||
|
||||
@ElementCollection
|
||||
@Column(name = "tag")
|
||||
@CollectionTable(name = "stack_tags", joinColumns = @JoinColumn(name = "stack_id"))
|
||||
private List<String> tags;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@JoinColumn(name = "workspaceconfig_id")
|
||||
private WorkspaceConfigImpl workspaceConfig;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "stack_components", joinColumns = @JoinColumn(name = "stack_id"))
|
||||
private List<StackComponentImpl> components;
|
||||
|
||||
@Embedded private StackIcon stackIcon;
|
||||
|
||||
public StackImpl() {}
|
||||
|
||||
public StackImpl(StackImpl stack) {
|
||||
this(
|
||||
stack.getId(),
|
||||
stack.getName(),
|
||||
stack.getDescription(),
|
||||
stack.getScope(),
|
||||
stack.getCreator(),
|
||||
stack.getTags(),
|
||||
stack.getWorkspaceConfig(),
|
||||
stack.getComponents(),
|
||||
stack.getStackIcon());
|
||||
}
|
||||
|
||||
public StackImpl(Stack stack) {
|
||||
this(
|
||||
stack.getId(),
|
||||
stack.getName(),
|
||||
stack.getDescription(),
|
||||
stack.getScope(),
|
||||
stack.getCreator(),
|
||||
stack.getTags(),
|
||||
stack.getWorkspaceConfig(),
|
||||
stack.getComponents(),
|
||||
null);
|
||||
}
|
||||
|
||||
public StackImpl(
|
||||
String id,
|
||||
String name,
|
||||
String description,
|
||||
String scope,
|
||||
String creator,
|
||||
List<String> tags,
|
||||
WorkspaceConfig workspaceConfig,
|
||||
List<? extends StackComponent> components,
|
||||
StackIcon stackIcon) {
|
||||
this.id = id;
|
||||
this.creator = creator;
|
||||
this.name = name;
|
||||
this.scope = scope;
|
||||
this.description = description;
|
||||
if (stackIcon != null) {
|
||||
this.stackIcon = new StackIcon(stackIcon);
|
||||
}
|
||||
if (tags != null) {
|
||||
this.tags = new ArrayList<>(tags);
|
||||
}
|
||||
if (workspaceConfig != null) {
|
||||
this.workspaceConfig = new WorkspaceConfigImpl(workspaceConfig);
|
||||
}
|
||||
if (components != null) {
|
||||
this.components = components.stream().map(StackComponentImpl::new).collect(toList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTags() {
|
||||
if (tags == null) {
|
||||
tags = new ArrayList<>();
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkspaceConfigImpl getWorkspaceConfig() {
|
||||
return workspaceConfig;
|
||||
}
|
||||
|
||||
public void setWorkspaceConfig(WorkspaceConfigImpl workspaceConfig) {
|
||||
this.workspaceConfig = workspaceConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StackComponentImpl> getComponents() {
|
||||
if (components == null) {
|
||||
components = new ArrayList<>();
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
public void setComponents(List<StackComponentImpl> components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
public StackIcon getStackIcon() {
|
||||
return stackIcon;
|
||||
}
|
||||
|
||||
public void setStackIcon(StackIcon stackIcon) {
|
||||
this.stackIcon = stackIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof StackImpl)) {
|
||||
return false;
|
||||
}
|
||||
final StackImpl that = (StackImpl) obj;
|
||||
return Objects.equals(id, that.id)
|
||||
&& Objects.equals(name, that.name)
|
||||
&& Objects.equals(description, that.description)
|
||||
&& Objects.equals(scope, that.scope)
|
||||
&& Objects.equals(creator, that.creator)
|
||||
&& getTags().equals(that.getTags())
|
||||
&& Objects.equals(workspaceConfig, that.workspaceConfig)
|
||||
&& getComponents().equals(that.getComponents())
|
||||
&& Objects.equals(stackIcon, that.stackIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Objects.hashCode(id);
|
||||
hash = 31 * hash + Objects.hashCode(name);
|
||||
hash = 31 * hash + Objects.hashCode(description);
|
||||
hash = 31 * hash + Objects.hashCode(scope);
|
||||
hash = 31 * hash + Objects.hashCode(creator);
|
||||
hash = 31 * hash + getTags().hashCode();
|
||||
hash = 31 * hash + Objects.hashCode(workspaceConfig);
|
||||
hash = 31 * hash + getComponents().hashCode();
|
||||
hash = 31 * hash + Objects.hashCode(stackIcon);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StackImpl{"
|
||||
+ "id='"
|
||||
+ id
|
||||
+ '\''
|
||||
+ ", name='"
|
||||
+ name
|
||||
+ '\''
|
||||
+ ", description='"
|
||||
+ description
|
||||
+ '\''
|
||||
+ ", scope='"
|
||||
+ scope
|
||||
+ '\''
|
||||
+ ", creator='"
|
||||
+ creator
|
||||
+ '\''
|
||||
+ ", tags="
|
||||
+ tags
|
||||
+ ", workspaceConfig="
|
||||
+ workspaceConfig
|
||||
+ ", components="
|
||||
+ components
|
||||
+ ", stackIcon="
|
||||
+ stackIcon
|
||||
+ '}';
|
||||
}
|
||||
|
||||
public static class StackBuilder {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String scope;
|
||||
private String creator;
|
||||
private List<String> tags;
|
||||
private WorkspaceConfig workspaceConfig;
|
||||
private StackSource source;
|
||||
private List<? extends StackComponent> components;
|
||||
private StackIcon stackIcon;
|
||||
|
||||
public StackBuilder generateId() {
|
||||
id = NameGenerator.generate("stack", 16);
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setScope(String scope) {
|
||||
this.scope = scope;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setTags(List<String> tags) {
|
||||
this.tags = (tags == null) ? new ArrayList<>() : tags;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setWorkspaceConfig(WorkspaceConfig workspaceConfig) {
|
||||
this.workspaceConfig = workspaceConfig;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setSource(StackSource source) {
|
||||
this.source = source;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setComponents(List<? extends StackComponent> components) {
|
||||
this.components = (components == null) ? new ArrayList<>() : components;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackBuilder setStackIcon(StackIcon stackIcon) {
|
||||
this.stackIcon = stackIcon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StackImpl build() {
|
||||
return new StackImpl(
|
||||
id, name, description, scope, creator, tags, workspaceConfig, components, stackIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,107 +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.spi;
|
||||
|
||||
import java.util.List;
|
||||
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.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Defines data access object for {@link StackImpl}
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
public interface StackDao {
|
||||
|
||||
/**
|
||||
* Create new Stack.
|
||||
*
|
||||
* @param stack stack to create
|
||||
* @throws NullPointerException when {@code stack} is null
|
||||
* @throws ConflictException when stack with id equal to {@code stack.getId()} is already exist
|
||||
* @throws ServerException when any error occurs
|
||||
*/
|
||||
void create(StackImpl stack) throws ConflictException, ServerException;
|
||||
|
||||
/**
|
||||
* Return existing stack by specified {@code id} or throws {@link NotFoundException} when stack
|
||||
* with such identifier doesn't exist.
|
||||
*
|
||||
* @param id the stack id
|
||||
* @throws NullPointerException when {@code id} is null
|
||||
* @throws NotFoundException if stack with {@code id} was not found
|
||||
* @throws ServerException when any error occurs
|
||||
*/
|
||||
StackImpl getById(String id) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Remove the stack by specified {@code id}.
|
||||
*
|
||||
* @param id stack identifier to remove stack
|
||||
* @throws NullPointerException when {@code id} is null
|
||||
* @throws ServerException when any error occurs
|
||||
*/
|
||||
void remove(String id) throws ServerException;
|
||||
|
||||
/**
|
||||
* Update stack with new entity, actually replaces(not merges) existed stack.
|
||||
*
|
||||
* <p>Existed stack will be fully updated(replaced), all data which wos present before update will
|
||||
* not be accessible with {@code update} anymore Expected update usage:
|
||||
*
|
||||
* <pre>
|
||||
* StackImpl stack = stackDao.getById("stack111");
|
||||
* ...
|
||||
* stack.setDescription("Java stack);
|
||||
* ...
|
||||
* stackDao.update(stack);
|
||||
* </pre>
|
||||
*
|
||||
* @param update the stack for update
|
||||
* @throws NullPointerException when {@code update} is null
|
||||
* @throws NotFoundException when stack with {@code update.getId()} doesn't exist
|
||||
* @throws ConflictException when stack with such name already exists
|
||||
* @throws ServerException when any error occurs
|
||||
*/
|
||||
StackImpl update(StackImpl update) throws NotFoundException, ConflictException, ServerException;
|
||||
|
||||
/**
|
||||
* Returns those stacks which match the following statements:
|
||||
*
|
||||
* <ul>
|
||||
* <li>If neither {@code user} no {@code tags} are specified(null values passed to the method)
|
||||
* then all the stacks which contain 'search' action in {@link StackImpl#getPublicActions()
|
||||
* public actions} are returned
|
||||
* <li>If {@code user} is specified then all the stacks which contain 'search' action in stack
|
||||
* public actions(like defined by previous list item) or those which specify 'search' action
|
||||
* in access control entry for given {@code user} are returned
|
||||
* <li>Finally, if {@code tags} are specified then the stacks which match 2 rules above, will be
|
||||
* filtered by the {@code tags}, stack should contain all of the {@code tags} to be in a
|
||||
* result list.
|
||||
* </ul>
|
||||
*
|
||||
* @param user user id for permission checking
|
||||
* @param tags stack tags to search stacks, may be {@code null}
|
||||
* @param skipCount count of items which should be skipped, if found items contain fewer than
|
||||
* {@code skipCount} items then return empty list items
|
||||
* @param maxItems max count of items to fetch
|
||||
* @return list stacks which contains all of specified {@code tags}
|
||||
* @throws ServerException when any error occurs
|
||||
* @throws IllegalArgumentException when {@code skipCount} or {@code maxItems} is negative
|
||||
*/
|
||||
List<StackImpl> searchStacks(
|
||||
@Nullable String user, @Nullable List<String> tags, int skipCount, int maxItems)
|
||||
throws ServerException;
|
||||
}
|
||||
|
|
@ -1,148 +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.stack;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
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.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
import org.eclipse.che.commons.lang.IoUtil;
|
||||
import org.eclipse.che.core.db.DBInitializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Class for loading list predefined {@link Stack} to the {@link StackDao} and set {@link StackIcon}
|
||||
* to the predefined stack.
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
* @author Sergii Leshchenko
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Singleton
|
||||
public class StackLoader {
|
||||
|
||||
public static final String CHE_PREDEFINED_STACKS = "che.predefined.stacks";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StackLoader.class);
|
||||
|
||||
protected final StackDao stackDao;
|
||||
|
||||
private final Gson GSON;
|
||||
private final Map<String, String> stacks2images;
|
||||
private final DBInitializer dbInitializer;
|
||||
private final Boolean reloadStacksOnStart;
|
||||
|
||||
@Inject
|
||||
@SuppressWarnings("unused")
|
||||
public StackLoader(
|
||||
@Named("che.predefined.stacks.reload_on_start") boolean reloadStacksOnStart,
|
||||
@Named(CHE_PREDEFINED_STACKS) Map<String, String> stacks2images,
|
||||
StackDao stackDao,
|
||||
DBInitializer dbInitializer) {
|
||||
this.reloadStacksOnStart = reloadStacksOnStart;
|
||||
this.stacks2images = stacks2images;
|
||||
this.stackDao = stackDao;
|
||||
this.dbInitializer = dbInitializer;
|
||||
GSON = new GsonBuilder().create();
|
||||
}
|
||||
|
||||
/** Load predefined stacks with their icons to the {@link StackDao}. */
|
||||
@PostConstruct
|
||||
public void start() {
|
||||
final boolean override;
|
||||
if (reloadStacksOnStart) {
|
||||
LOG.warn("Reload stacks on start is deprecated policy, and it will be removed soon");
|
||||
override = true;
|
||||
} else {
|
||||
override = dbInitializer.isBareInit();
|
||||
}
|
||||
if (override) {
|
||||
for (Map.Entry<String, String> stack2image : stacks2images.entrySet()) {
|
||||
final String stackFile = stack2image.getKey();
|
||||
final String imagesDir = stack2image.getValue();
|
||||
try (BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(IoUtil.getResource(stackFile)))) {
|
||||
List<StackImpl> stacks =
|
||||
GSON.fromJson(reader, new TypeToken<List<StackImpl>>() {}.getType());
|
||||
final Path imagesDirPath = !isNullOrEmpty(imagesDir) ? Paths.get(imagesDir) : null;
|
||||
stacks.forEach(stack -> loadStack(stack, imagesDirPath));
|
||||
} catch (Exception ex) {
|
||||
LOG.error("Failed to store stacks from '{}'", stackFile);
|
||||
}
|
||||
}
|
||||
LOG.info("Stacks initialization finished");
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadStack(StackImpl stack, Path imagePath) {
|
||||
setIconData(stack, imagePath);
|
||||
try {
|
||||
try {
|
||||
stackDao.update(stack);
|
||||
} catch (NotFoundException ex) {
|
||||
stackDao.create(stack);
|
||||
}
|
||||
} catch (ServerException | ConflictException ex) {
|
||||
LOG.warn(format("Failed to load stack with id '%s' ", stack.getId()), ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for stack icon and set image data into given stack.
|
||||
*
|
||||
* @param stack stack for icon setup
|
||||
* @param stackIconFolderPath path to icon folder
|
||||
*/
|
||||
protected void setIconData(StackImpl stack, Path stackIconFolderPath) {
|
||||
StackIcon stackIcon = stack.getStackIcon();
|
||||
if (stackIcon == null) {
|
||||
return;
|
||||
}
|
||||
if (stackIconFolderPath == null) {
|
||||
stack.setStackIcon(null);
|
||||
LOG.warn("No configured image found for stack {}", stack.getId());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final Path stackIconPath = stackIconFolderPath.resolve(stackIcon.getName());
|
||||
final byte[] imageData = IOUtils.toByteArray(IoUtil.getResource(stackIconPath.toString()));
|
||||
stackIcon = new StackIcon(stackIcon.getName(), stackIcon.getMediaType(), imageData);
|
||||
stack.setStackIcon(stackIcon);
|
||||
} catch (IOException ex) {
|
||||
stack.setStackIcon(null);
|
||||
LOG.error(
|
||||
format("Failed to load stack icon data for the stack with id '%s'", stack.getId()), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,364 +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.stack;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA;
|
||||
import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
|
||||
import static javax.ws.rs.core.Response.Status.CREATED;
|
||||
import static org.eclipse.che.api.workspace.server.DtoConverter.asDto;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_CREATE_STACK;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_DELETE_ICON;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_GET_ICON;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_GET_STACK_BY_ID;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_REMOVE_STACK;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_SEARCH_STACKS;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_UPDATE_STACK;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_UPLOAD_ICON;
|
||||
|
||||
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.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
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 javax.ws.rs.core.UriBuilder;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.eclipse.che.api.core.ApiException;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.core.rest.annotations.GenerateLink;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.core.util.LinksHelper;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
|
||||
/**
|
||||
* Defines Stack REST API
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
@Api(value = "/stack", description = "Stack REST API")
|
||||
@Path("/stack")
|
||||
public class StackService extends Service {
|
||||
|
||||
private final StackDao stackDao;
|
||||
private final StackValidator stackValidator;
|
||||
|
||||
@Inject
|
||||
public StackService(StackDao stackDao, StackValidator stackValidator) {
|
||||
this.stackDao = stackDao;
|
||||
this.stackValidator = stackValidator;
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_CREATE_STACK)
|
||||
@ApiOperation(
|
||||
value = "Create a new stack",
|
||||
notes = "This operation can be performed only by authorized user",
|
||||
response = StackDto.class)
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 201, message = "The stack 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 stack"),
|
||||
@ApiResponse(
|
||||
code = 409,
|
||||
message =
|
||||
"Conflict error occurred during the stack creation"
|
||||
+ "(e.g. The stack with such name already exists)"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public Response createStack(@ApiParam("The new stack") final StackDto stackDto)
|
||||
throws ApiException {
|
||||
stackValidator.check(stackDto);
|
||||
final String userId = EnvironmentContext.getCurrent().getSubject().getUserId();
|
||||
final StackImpl newStack =
|
||||
StackImpl.builder()
|
||||
.generateId()
|
||||
.setName(stackDto.getName())
|
||||
.setDescription(stackDto.getDescription())
|
||||
.setScope(stackDto.getScope())
|
||||
.setCreator(userId)
|
||||
.setTags(stackDto.getTags())
|
||||
.setWorkspaceConfig(stackDto.getWorkspaceConfig())
|
||||
.setComponents(stackDto.getComponents())
|
||||
.build();
|
||||
stackDao.create(newStack);
|
||||
|
||||
return Response.status(CREATED).entity(asStackDto(newStack)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_GET_STACK_BY_ID)
|
||||
@ApiOperation(
|
||||
value = "Get the stack by id",
|
||||
notes = "This operation can be performed for stack owner, or for predefined stacks")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The response contains requested stack entity"),
|
||||
@ApiResponse(code = 404, message = "The requested stack was not found"),
|
||||
@ApiResponse(code = 403, message = "The user has not permission get requested stack"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public StackDto getStack(@ApiParam("The stack id") @PathParam("id") final String id)
|
||||
throws ApiException {
|
||||
return asStackDto(stackDao.getById(id));
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
@Produces(APPLICATION_JSON)
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_UPDATE_STACK)
|
||||
@ApiOperation(
|
||||
value =
|
||||
"Update the stack by replacing all the existing data (exclude field \"creator\") with update")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The stack 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 stack"),
|
||||
@ApiResponse(
|
||||
code = 409,
|
||||
message =
|
||||
"Conflict error occurred during stack update"
|
||||
+ "(e.g. Stack with such name already exists)"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public StackDto updateStack(
|
||||
@ApiParam(value = "The stack update", required = true) final StackDto updateDto,
|
||||
@ApiParam(value = "The stack id", required = true) @PathParam("id") final String id)
|
||||
throws ApiException {
|
||||
stackValidator.check(updateDto);
|
||||
final StackImpl stack = stackDao.getById(id);
|
||||
|
||||
StackImpl stackForUpdate =
|
||||
StackImpl.builder()
|
||||
.setId(id)
|
||||
.setName(updateDto.getName())
|
||||
.setDescription(updateDto.getDescription())
|
||||
.setScope(updateDto.getScope())
|
||||
// user can't edit creator
|
||||
.setCreator(stack.getCreator())
|
||||
.setTags(updateDto.getTags())
|
||||
.setWorkspaceConfig(updateDto.getWorkspaceConfig())
|
||||
.setComponents(updateDto.getComponents())
|
||||
.build();
|
||||
|
||||
return asStackDto(stackDao.update(stackForUpdate));
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
@GenerateLink(rel = LINK_REL_REMOVE_STACK)
|
||||
@ApiOperation(value = "Removes the stack")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 204, message = "The stack successfully removed"),
|
||||
@ApiResponse(code = 403, message = "The user does not have access to remove the stack"),
|
||||
@ApiResponse(code = 404, message = "The stack doesn't exist"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public void removeStack(@ApiParam("The stack id") @PathParam("id") final String id)
|
||||
throws ApiException {
|
||||
stackDao.remove(id);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_SEARCH_STACKS)
|
||||
@ApiOperation(
|
||||
value = "Get the list stacks with required tags",
|
||||
notes = "This operation can be performed only by authorized user",
|
||||
response = StackDto.class,
|
||||
responseContainer = "List")
|
||||
@ApiResponses({
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "The response contains requested list stack entity with required tags"),
|
||||
@ApiResponse(
|
||||
code = 403,
|
||||
message = "The user does not have access to get stack entity list with required tags"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public List<StackDto> searchStacks(
|
||||
@ApiParam("List tags for search") @QueryParam("tags") final List<String> tags,
|
||||
@ApiParam(value = "The number of the items to skip")
|
||||
@DefaultValue("0")
|
||||
@QueryParam("skipCount")
|
||||
final Integer skipCount,
|
||||
@ApiParam("The limit of the items in the response, default is 30")
|
||||
@DefaultValue("30")
|
||||
@QueryParam("maxItems")
|
||||
final Integer maxItems)
|
||||
throws ServerException {
|
||||
final String currentUser = EnvironmentContext.getCurrent().getSubject().getUserId();
|
||||
return stackDao
|
||||
.searchStacks(currentUser, tags, skipCount, maxItems)
|
||||
.stream()
|
||||
.map(this::asStackDto)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}/icon")
|
||||
@Produces("image/*")
|
||||
@GenerateLink(rel = LINK_REL_GET_ICON)
|
||||
@ApiOperation(
|
||||
value = "Get icon by stack id",
|
||||
notes = "This operation can be performed only by authorized user",
|
||||
response = byte[].class)
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "The response contains requested image entity"),
|
||||
@ApiResponse(code = 403, message = "The user does not have access to get image entity"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public Response getIcon(@ApiParam("The stack id") @PathParam("id") final String id)
|
||||
throws NotFoundException, ServerException, BadRequestException {
|
||||
StackImpl stack = stackDao.getById(id);
|
||||
|
||||
if (stack == null) {
|
||||
throw new NotFoundException("Stack with id '" + id + "' was not found.");
|
||||
}
|
||||
|
||||
StackIcon image = stack.getStackIcon();
|
||||
|
||||
if (image == null) {
|
||||
throw new NotFoundException("Image for stack with id '" + id + "' was not found.");
|
||||
}
|
||||
return Response.ok(image.getData(), image.getMediaType()).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{id}/icon")
|
||||
@Consumes(MULTIPART_FORM_DATA)
|
||||
@Produces(TEXT_PLAIN)
|
||||
@GenerateLink(rel = LINK_REL_UPLOAD_ICON)
|
||||
@ApiOperation(
|
||||
value = "Upload icon for required stack",
|
||||
notes = "This operation can be performed only by authorized stack owner")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 200, message = "Image was successfully uploaded"),
|
||||
@ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"),
|
||||
@ApiResponse(
|
||||
code = 403,
|
||||
message = "The user does not have access upload image for stack with required id"),
|
||||
@ApiResponse(code = 404, message = "The stack doesn't exist"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public Response uploadIcon(
|
||||
@ApiParam("The image for stack") final Iterator<FileItem> formData,
|
||||
@ApiParam("The stack id") @PathParam("id") final String id)
|
||||
throws NotFoundException, ServerException, BadRequestException, ForbiddenException,
|
||||
ConflictException {
|
||||
if (formData.hasNext()) {
|
||||
FileItem fileItem = formData.next();
|
||||
StackIcon stackIcon =
|
||||
new StackIcon(fileItem.getName(), fileItem.getContentType(), fileItem.get());
|
||||
|
||||
StackImpl stack = stackDao.getById(id);
|
||||
|
||||
stack.setStackIcon(stackIcon);
|
||||
stackDao.update(stack);
|
||||
}
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/{id}/icon")
|
||||
@GenerateLink(rel = LINK_REL_DELETE_ICON)
|
||||
@ApiOperation(
|
||||
value = "Delete icon for required stack",
|
||||
notes = "This operation can be performed only by authorized stack owner")
|
||||
@ApiResponses({
|
||||
@ApiResponse(code = 204, message = "Icon was successfully removed"),
|
||||
@ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"),
|
||||
@ApiResponse(
|
||||
code = 403,
|
||||
message = "The user does not have access upload image for stack with required id"),
|
||||
@ApiResponse(code = 404, message = "The stack or icon doesn't exist"),
|
||||
@ApiResponse(
|
||||
code = 409,
|
||||
message =
|
||||
"Conflict error occurred during stack update"
|
||||
+ "(e.g. Stack with such name already exists)"),
|
||||
@ApiResponse(code = 500, message = "Internal server error occurred")
|
||||
})
|
||||
public void removeIcon(@ApiParam("The stack Id") @PathParam("id") final String id)
|
||||
throws NotFoundException, ServerException, ConflictException, ForbiddenException,
|
||||
BadRequestException {
|
||||
StackImpl stack = stackDao.getById(id);
|
||||
stack.setStackIcon(null);
|
||||
stackDao.update(stack);
|
||||
}
|
||||
|
||||
private StackDto asStackDto(StackImpl stack) {
|
||||
final UriBuilder builder = getServiceContext().getServiceUriBuilder();
|
||||
|
||||
List<Link> links = new ArrayList<>();
|
||||
final Link removeLink =
|
||||
LinksHelper.createLink(
|
||||
"DELETE",
|
||||
builder.clone().path(getClass(), "removeStack").build(stack.getId()).toString(),
|
||||
LINK_REL_REMOVE_STACK);
|
||||
final Link getLink =
|
||||
LinksHelper.createLink(
|
||||
"GET",
|
||||
builder.clone().path(getClass(), "getStack").build(stack.getId()).toString(),
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_STACK_BY_ID);
|
||||
links.add(removeLink);
|
||||
links.add(getLink);
|
||||
|
||||
StackIcon stackIcon = stack.getStackIcon();
|
||||
if (stackIcon != null) {
|
||||
Link deleteIcon =
|
||||
LinksHelper.createLink(
|
||||
"DELETE",
|
||||
builder.clone().path(getClass(), "removeIcon").build(stack.getId()).toString(),
|
||||
stackIcon.getMediaType(),
|
||||
LINK_REL_DELETE_ICON);
|
||||
Link getIconLink =
|
||||
LinksHelper.createLink(
|
||||
"GET",
|
||||
builder.clone().path(getClass(), "getIcon").build(stack.getId()).toString(),
|
||||
stackIcon.getMediaType(),
|
||||
LINK_REL_GET_ICON);
|
||||
links.add(deleteIcon);
|
||||
links.add(getIconLink);
|
||||
}
|
||||
return asDto(stack).withLinks(links);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +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.stack;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.ValidationException;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceValidator;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
|
||||
/**
|
||||
* Validator for {@link Stack} objects
|
||||
*
|
||||
* @author Mihail Kuznyetsov
|
||||
*/
|
||||
@Singleton
|
||||
public class StackValidator {
|
||||
|
||||
@Inject private WorkspaceValidator wsValidator;
|
||||
|
||||
/**
|
||||
* Validate stack object
|
||||
*
|
||||
* @param stack stack to validate
|
||||
* @throws BadRequestException if stack is not valid
|
||||
*/
|
||||
public void check(Stack stack) throws BadRequestException, ServerException, NotFoundException {
|
||||
if (stack == null) {
|
||||
throw new BadRequestException("Required non-null stack");
|
||||
}
|
||||
if (stack.getName() == null || stack.getName().isEmpty()) {
|
||||
throw new BadRequestException("Required non-null and non-empty stack name");
|
||||
}
|
||||
if (stack.getScope() == null
|
||||
|| !stack.getScope().equals("general") && !stack.getScope().equals("advanced")) {
|
||||
throw new BadRequestException("Required non-null scope value: 'general' or 'advanced'");
|
||||
}
|
||||
if (stack.getWorkspaceConfig() == null) {
|
||||
throw new BadRequestException("Workspace config required");
|
||||
}
|
||||
try {
|
||||
wsValidator.validateConfig(stack.getWorkspaceConfig());
|
||||
} catch (ValidationException x) {
|
||||
throw new BadRequestException(x.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,96 +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.stack.image;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import java.util.Arrays;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Class for storing {@link org.eclipse.che.api.workspace.shared.stack.Stack} icon data
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
@Embeddable
|
||||
public class StackIcon {
|
||||
|
||||
@Column(name = "icon_name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "mediatype")
|
||||
private String mediaType;
|
||||
|
||||
@Column(name = "data")
|
||||
private byte[] data;
|
||||
|
||||
public StackIcon() {}
|
||||
|
||||
public StackIcon(String name, String mediaType, @Nullable byte[] data) {
|
||||
this.data = data;
|
||||
this.mediaType = mediaType;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public StackIcon(StackIcon icon) {
|
||||
this(icon.name, icon.mediaType, Arrays.copyOf(icon.data, icon.data.length));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof StackIcon)) {
|
||||
return false;
|
||||
}
|
||||
StackIcon another = (StackIcon) obj;
|
||||
return Objects.equal(name, another.name)
|
||||
&& Objects.equal(mediaType, another.mediaType)
|
||||
&& Arrays.equals(data, another.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Objects.hashCode(name);
|
||||
hash = 31 * hash + Objects.hashCode(mediaType);
|
||||
hash = 31 * hash + Arrays.hashCode(data);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StackIcon{"
|
||||
+ "name='"
|
||||
+ name
|
||||
+ '\''
|
||||
+ ", mediaType='"
|
||||
+ mediaType
|
||||
+ '\''
|
||||
+ ", data=[byte array]"
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
@ -167,7 +167,6 @@ public class WorkspaceServiceTest {
|
|||
SECURE_PATH
|
||||
+ "/workspace"
|
||||
+ "?namespace=test"
|
||||
+ "&attribute=stackId:stack123"
|
||||
+ "&attribute=factoryId:factory123"
|
||||
+ "&attribute=custom:custom:value");
|
||||
|
||||
|
|
@ -180,7 +179,6 @@ public class WorkspaceServiceTest {
|
|||
eq("test"),
|
||||
eq(
|
||||
ImmutableMap.of(
|
||||
"stackId", "stack123",
|
||||
"factoryId", "factory123",
|
||||
"custom", "custom:value")));
|
||||
}
|
||||
|
|
@ -206,7 +204,6 @@ public class WorkspaceServiceTest {
|
|||
SECURE_PATH
|
||||
+ "/workspace/devfile"
|
||||
+ "?namespace=test"
|
||||
+ "&attribute=stackId:stack123"
|
||||
+ "&attribute=factoryId:factory123"
|
||||
+ "&attribute=custom:custom:value");
|
||||
|
||||
|
|
@ -219,7 +216,6 @@ public class WorkspaceServiceTest {
|
|||
eq("test"),
|
||||
eq(
|
||||
ImmutableMap.of(
|
||||
"stackId", "stack123",
|
||||
"factoryId", "factory123",
|
||||
"custom", "custom:value")),
|
||||
any());
|
||||
|
|
@ -245,7 +241,6 @@ public class WorkspaceServiceTest {
|
|||
SECURE_PATH
|
||||
+ "/workspace/devfile"
|
||||
+ "?namespace=test"
|
||||
+ "&attribute=stackId:stack123"
|
||||
+ "&attribute=factoryId:factory123"
|
||||
+ "&attribute=custom:custom:value");
|
||||
|
||||
|
|
@ -258,7 +253,6 @@ public class WorkspaceServiceTest {
|
|||
eq("test"),
|
||||
eq(
|
||||
ImmutableMap.of(
|
||||
"stackId", "stack123",
|
||||
"factoryId", "factory123",
|
||||
"custom", "custom:value")),
|
||||
any());
|
||||
|
|
@ -285,7 +279,6 @@ public class WorkspaceServiceTest {
|
|||
SECURE_PATH
|
||||
+ "/workspace/devfile"
|
||||
+ "?namespace=test"
|
||||
+ "&attribute=stackId:stack123"
|
||||
+ "&attribute=factoryId:factory123"
|
||||
+ "&attribute=custom:custom:value");
|
||||
|
||||
|
|
@ -314,8 +307,7 @@ public class WorkspaceServiceTest {
|
|||
.post(
|
||||
SECURE_PATH
|
||||
+ "/workspace"
|
||||
+ "?attribute=stackId:stack123"
|
||||
+ "&attribute=factoryId:factory123"
|
||||
+ "?attribute=factoryId:factory123"
|
||||
+ "&attribute=custom:custom:value");
|
||||
|
||||
assertEquals(response.getStatusCode(), 201);
|
||||
|
|
@ -327,7 +319,6 @@ public class WorkspaceServiceTest {
|
|||
eq(NAMESPACE),
|
||||
eq(
|
||||
ImmutableMap.of(
|
||||
"stackId", "stack123",
|
||||
"factoryId", "factory123",
|
||||
"custom", "custom:value")));
|
||||
}
|
||||
|
|
@ -348,8 +339,7 @@ public class WorkspaceServiceTest {
|
|||
.post(
|
||||
SECURE_PATH
|
||||
+ "/workspace"
|
||||
+ "?attribute=stackId:stack123"
|
||||
+ "&attribute=factoryId:factory123"
|
||||
+ "?attribute=factoryId:factory123"
|
||||
+ "&attribute=custom:custom:value"
|
||||
+ "&start-after-create=true");
|
||||
|
||||
|
|
@ -360,7 +350,6 @@ public class WorkspaceServiceTest {
|
|||
anyString(),
|
||||
eq(
|
||||
ImmutableMap.of(
|
||||
"stackId", "stack123",
|
||||
"factoryId", "factory123",
|
||||
"custom", "custom:value")));
|
||||
}
|
||||
|
|
@ -374,12 +363,12 @@ public class WorkspaceServiceTest {
|
|||
.contentType("application/json")
|
||||
.body(createConfigDto())
|
||||
.when()
|
||||
.post(SECURE_PATH + "/workspace?attribute=stackId=stack123");
|
||||
.post(SECURE_PATH + "/workspace?attribute=factoryId=factoryId123");
|
||||
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
assertEquals(
|
||||
unwrapError(response),
|
||||
"Attribute 'stackId=stack123' is not valid, "
|
||||
"Attribute 'factoryId=factoryId123' is not valid, "
|
||||
+ "it should contain name and value separated "
|
||||
+ "with colon. For example: attributeName:attributeValue");
|
||||
}
|
||||
|
|
@ -407,11 +396,7 @@ public class WorkspaceServiceTest {
|
|||
.body(configDto)
|
||||
.when()
|
||||
.post(
|
||||
SECURE_PATH
|
||||
+ "/workspace"
|
||||
+ "?namespace=test"
|
||||
+ "&attribute=stackId:stack123"
|
||||
+ "&attribute=custom:custom:value");
|
||||
SECURE_PATH + "/workspace" + "?namespace=test" + "&attribute=custom:custom:value");
|
||||
|
||||
assertEquals(response.getStatusCode(), 201);
|
||||
String savedLocation =
|
||||
|
|
@ -433,7 +418,7 @@ public class WorkspaceServiceTest {
|
|||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.post(SECURE_PATH + "/workspace?attribute=stackId=stack123");
|
||||
.post(SECURE_PATH + "/workspace");
|
||||
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
assertEquals(unwrapError(response), "Workspace configuration required");
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ 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.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
|
|
@ -70,7 +68,6 @@ public class WorkspaceTckModule extends TckModule {
|
|||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
StackImpl.class,
|
||||
CommandImpl.class,
|
||||
RecipeImpl.class,
|
||||
VolumeImpl.class,
|
||||
|
|
@ -97,10 +94,8 @@ public class WorkspaceTckModule extends TckModule {
|
|||
bind(new TypeLiteral<TckRepository<AccountImpl>>() {})
|
||||
.toInstance(new JpaTckRepository<>(AccountImpl.class));
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {}).toInstance(new WorkspaceRepository());
|
||||
bind(new TypeLiteral<TckRepository<StackImpl>>() {}).toInstance(new StackRepository());
|
||||
|
||||
bind(WorkspaceDao.class).to(JpaWorkspaceDao.class);
|
||||
bind(StackDao.class).to(JpaStackDao.class);
|
||||
}
|
||||
|
||||
private static class WorkspaceRepository extends JpaTckRepository<WorkspaceImpl> {
|
||||
|
|
@ -119,18 +114,4 @@ public class WorkspaceTckModule extends TckModule {
|
|||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StackRepository extends JpaTckRepository<StackImpl> {
|
||||
public StackRepository() {
|
||||
super(StackImpl.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAll(Collection<? extends StackImpl> entities) throws TckRepositoryException {
|
||||
for (StackImpl stack : entities) {
|
||||
stack.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,312 +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.spi.tck;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.api.workspace.server.spi.tck.WorkspaceDaoTest.createWorkspaceConfig;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
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.workspace.server.event.BeforeStackRemovedEvent;
|
||||
import org.eclipse.che.api.workspace.server.event.StackPersistedEvent;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
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.core.db.cascade.CascadeEventSubscriber;
|
||||
import org.eclipse.che.core.db.cascade.event.CascadeEvent;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link StackDao} contract.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Listeners(TckListener.class)
|
||||
@Test(suiteName = StackDaoTest.SUITE_NAME)
|
||||
public class StackDaoTest {
|
||||
|
||||
public static final String SUITE_NAME = "StackDaoTck";
|
||||
|
||||
private static final int STACKS_SIZE = 5;
|
||||
|
||||
private StackImpl[] stacks;
|
||||
|
||||
@Inject private TckRepository<StackImpl> stackRepo;
|
||||
|
||||
@Inject private StackDao stackDao;
|
||||
|
||||
@Inject private EventService eventService;
|
||||
|
||||
@BeforeMethod
|
||||
private void createStacks() throws TckRepositoryException {
|
||||
stacks = new StackImpl[STACKS_SIZE];
|
||||
for (int i = 0; i < STACKS_SIZE; i++) {
|
||||
stacks[i] = createStack("stack-" + i, "name-" + i);
|
||||
}
|
||||
stackRepo.createAll(Stream.of(stacks).map(StackImpl::new).collect(toList()));
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
private void removeStacks() throws TckRepositoryException {
|
||||
stackRepo.removeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetById() throws Exception {
|
||||
final StackImpl stack = stacks[0];
|
||||
|
||||
assertEquals(stackDao.getById(stack.getId()), stack);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class)
|
||||
public void shouldThrowNotFoundExceptionWhenGettingNonExistingStack() throws Exception {
|
||||
stackDao.getById("non-existing-stack");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenGettingStackByNullKey() throws Exception {
|
||||
stackDao.getById(null);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "shouldGetById")
|
||||
public void shouldCreateStack() throws Exception {
|
||||
final StackImpl stack = createStack("new-stack", "new-stack-name");
|
||||
|
||||
stackDao.create(stack);
|
||||
|
||||
assertEquals(stackDao.getById(stack.getId()), new StackImpl(stack));
|
||||
}
|
||||
|
||||
@Test(
|
||||
dependsOnMethods = "shouldThrowNotFoundExceptionWhenGettingNonExistingStack",
|
||||
expectedExceptions = NotFoundException.class)
|
||||
public void shouldNotCreateStackWhenSubscriberThrowsExceptionOnStackStoring() throws Exception {
|
||||
final StackImpl stack = createStack("new-stack", "new-stack-name");
|
||||
|
||||
CascadeEventSubscriber<StackPersistedEvent> subscriber = mockCascadeEventSubscriber();
|
||||
doThrow(new ConflictException("error")).when(subscriber).onCascadeEvent(any());
|
||||
eventService.subscribe(subscriber, StackPersistedEvent.class);
|
||||
|
||||
try {
|
||||
stackDao.create(stack);
|
||||
fail("StackDao#create had to throw conflict exception");
|
||||
} catch (ConflictException ignored) {
|
||||
}
|
||||
|
||||
eventService.unsubscribe(subscriber, StackPersistedEvent.class);
|
||||
stackDao.getById(stack.getId());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ConflictException.class)
|
||||
public void shouldThrowConflictExceptionWhenCreatingStackWithIdThatAlreadyExists()
|
||||
throws Exception {
|
||||
final StackImpl stack = createStack(stacks[0].getId(), "new-name");
|
||||
|
||||
stackDao.create(stack);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ConflictException.class)
|
||||
public void shouldThrowConflictExceptionWhenCreatingStackWithNameThatAlreadyExists()
|
||||
throws Exception {
|
||||
final StackImpl stack = createStack("new-stack-id", stacks[0].getName());
|
||||
|
||||
stackDao.create(stack);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenCreatingNullStack() throws Exception {
|
||||
stackDao.create(null);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = NotFoundException.class,
|
||||
dependsOnMethods = "shouldThrowNotFoundExceptionWhenGettingNonExistingStack")
|
||||
public void shouldRemoveStack() throws Exception {
|
||||
final StackImpl stack = stacks[0];
|
||||
|
||||
stackDao.remove(stack.getId());
|
||||
|
||||
// Should throw an exception
|
||||
stackDao.getById(stack.getId());
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "shouldGetById")
|
||||
public void shouldNotRemoveStackWhenSubscriberThrowsExceptionOnStackRemoving() throws Exception {
|
||||
final StackImpl stack = stacks[0];
|
||||
CascadeEventSubscriber<BeforeStackRemovedEvent> subscriber = mockCascadeEventSubscriber();
|
||||
doThrow(new ServerException("error")).when(subscriber).onCascadeEvent(any());
|
||||
eventService.subscribe(subscriber, BeforeStackRemovedEvent.class);
|
||||
|
||||
try {
|
||||
stackDao.remove(stack.getId());
|
||||
fail("StackDao#remove had to throw server exception");
|
||||
} catch (ServerException ignored) {
|
||||
}
|
||||
|
||||
assertEquals(stackDao.getById(stack.getId()), stack);
|
||||
eventService.unsubscribe(subscriber, BeforeStackRemovedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotThrowAnyExceptionWhenRemovingNonExistingStack() throws Exception {
|
||||
stackDao.remove("non-existing");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenRemovingNull() throws Exception {
|
||||
stackDao.remove(null);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "shouldGetById")
|
||||
public void shouldUpdateStack() throws Exception {
|
||||
final StackImpl stack = stacks[0];
|
||||
|
||||
stack.setName("new-name");
|
||||
stack.setCreator("new-creator");
|
||||
stack.setDescription("new-description");
|
||||
stack.setScope("new-scope");
|
||||
stack.getTags().clear();
|
||||
stack.getTags().add("new-tag");
|
||||
|
||||
// Remove an existing component
|
||||
stack.getComponents().remove(1);
|
||||
|
||||
// Add a new component
|
||||
stack.getComponents().add(new StackComponentImpl("component3", "component3-version"));
|
||||
|
||||
// Update an existing component
|
||||
final StackComponentImpl component = stack.getComponents().get(0);
|
||||
component.setName("new-name");
|
||||
component.setVersion("new-version");
|
||||
|
||||
// Set a new icon
|
||||
stack.setStackIcon(new StackIcon("new-name", "new-media", "new-data".getBytes()));
|
||||
|
||||
stackDao.update(stack);
|
||||
|
||||
assertEquals(stackDao.getById(stack.getId()), new StackImpl(stack));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ConflictException.class)
|
||||
public void shouldNotUpdateStackIfNewNameIsReserved() throws Exception {
|
||||
final StackImpl stack = stacks[0];
|
||||
stack.setName(stacks[1].getName());
|
||||
|
||||
stackDao.update(stack);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class)
|
||||
public void shouldThrowNotFoundExceptionWhenUpdatingNonExistingStack() throws Exception {
|
||||
stackDao.update(createStack("new-stack", "new-stack-name"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenUpdatingNullStack() throws Exception {
|
||||
stackDao.update(null);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "shouldUpdateStack")
|
||||
public void shouldFindStacksWithSpecifiedTags() throws Exception {
|
||||
stacks[0].getTags().addAll(asList("search-tag1", "search-tag2"));
|
||||
stacks[1].getTags().addAll(asList("search-tag1", "non-search-tag"));
|
||||
stacks[2].getTags().addAll(asList("non-search-tag", "search-tag2"));
|
||||
stacks[3].getTags().addAll(asList("search-tag1", "search-tag2", "another-tag"));
|
||||
updateAll();
|
||||
|
||||
final List<StackImpl> found =
|
||||
stackDao.searchStacks(null, asList("search-tag1", "search-tag2"), 0, 0);
|
||||
found.forEach(s -> Collections.sort(s.getTags()));
|
||||
for (StackImpl stack : stacks) {
|
||||
Collections.sort(stack.getTags());
|
||||
}
|
||||
|
||||
assertEquals(new HashSet<>(found), new HashSet<>(asList(stacks[0], stacks[3])));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnAllStacksWhenSearchingWithoutTags() throws Exception {
|
||||
final List<StackImpl> found = stackDao.searchStacks(null, null, 0, 0);
|
||||
found.forEach(s -> Collections.sort(s.getTags()));
|
||||
for (StackImpl stack : stacks) {
|
||||
Collections.sort(stack.getTags());
|
||||
}
|
||||
|
||||
assertEquals(new HashSet<>(found), new HashSet<>(asList(stacks)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPublishStackPersistedEventAfterStackIsPersisted() throws Exception {
|
||||
final boolean[] isNotified = new boolean[] {false};
|
||||
eventService.subscribe(event -> isNotified[0] = true, StackPersistedEvent.class);
|
||||
|
||||
stackDao.create(createStack("test", "test"));
|
||||
|
||||
assertTrue(isNotified[0], "Event subscriber notified");
|
||||
}
|
||||
|
||||
private void updateAll() throws ConflictException, NotFoundException, ServerException {
|
||||
for (StackImpl stack : stacks) {
|
||||
stackDao.update(stack);
|
||||
}
|
||||
}
|
||||
|
||||
private static StackImpl createStack(String id, String name) {
|
||||
final StackImpl stack =
|
||||
StackImpl.builder()
|
||||
.setId(id)
|
||||
.setName(name)
|
||||
.setCreator("user123")
|
||||
.setDescription(id + "-description")
|
||||
.setScope(id + "-scope")
|
||||
.setTags(asList(id + "-tag1", id + "-tag2"))
|
||||
.setComponents(
|
||||
asList(
|
||||
new StackComponentImpl(id + "-component1", id + "-component1-version"),
|
||||
new StackComponentImpl(id + "-component2", id + "-component2-version")))
|
||||
.setStackIcon(
|
||||
new StackIcon(id + "-icon", id + "-media-type", "0x1234567890abcdef".getBytes()))
|
||||
.build();
|
||||
final WorkspaceConfigImpl config = createWorkspaceConfig("test");
|
||||
stack.setWorkspaceConfig(config);
|
||||
return stack;
|
||||
}
|
||||
|
||||
private <T extends CascadeEvent> CascadeEventSubscriber<T> mockCascadeEventSubscriber() {
|
||||
@SuppressWarnings("unchecked")
|
||||
CascadeEventSubscriber<T> subscriber = mock(CascadeEventSubscriber.class);
|
||||
doCallRealMethod().when(subscriber).onEvent(any());
|
||||
return subscriber;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,229 +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.stack;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.shared.dto.CommandDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.MachineConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectProblemDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.RecipeDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ServerConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackComponentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackDto;
|
||||
import org.eclipse.che.core.db.DBInitializer;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link StackLoader}
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class StackLoaderTest {
|
||||
|
||||
@Mock private StackDao stackDao;
|
||||
|
||||
@Mock private DBInitializer dbInitializer;
|
||||
|
||||
private StackLoader stackLoader;
|
||||
|
||||
@BeforeMethod
|
||||
public void startup() throws Exception {
|
||||
when(dbInitializer.isBareInit()).thenReturn(true);
|
||||
stackLoader =
|
||||
new StackLoader(
|
||||
false, ImmutableMap.of("stacks.json", "stack_img"), stackDao, dbInitializer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void predefinedStackWithValidJsonShouldBeUpdated() throws Exception {
|
||||
stackLoader.start();
|
||||
|
||||
verify(stackDao, times(5)).update(any());
|
||||
verify(stackDao, never()).create(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void predefinedStackWithValidJsonShouldBeCreated() throws Exception {
|
||||
doThrow(new NotFoundException("Stack is already exist")).when(stackDao).update(any());
|
||||
|
||||
stackLoader.start();
|
||||
|
||||
verify(stackDao, times(5)).update(any());
|
||||
verify(stackDao, times(5)).create(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doNotThrowExceptionWhenUpdateFailed() throws Exception {
|
||||
doThrow(new ServerException("Internal server error")).when(stackDao).update(any());
|
||||
|
||||
stackLoader.start();
|
||||
|
||||
verify(stackDao, times(5)).update(any());
|
||||
verify(stackDao, never()).create(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doNotThrowExceptionWhenCreationFailed() throws Exception {
|
||||
doThrow(new NotFoundException("Not found")).when(stackDao).update(any());
|
||||
doThrow(new ServerException("Internal server error")).when(stackDao).create(any());
|
||||
|
||||
stackLoader.start();
|
||||
|
||||
verify(stackDao, times(5)).update(any());
|
||||
verify(stackDao, times(5)).create(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideStacksWithoutImages() throws Exception {
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
map.put("stacks.json", null);
|
||||
stackLoader = new StackLoader(true, map, stackDao, dbInitializer);
|
||||
|
||||
stackLoader.start();
|
||||
|
||||
verify(stackDao, times(5)).update(any());
|
||||
verify(stackDao, never()).create(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotLoadStackWhenDBAlreadyInitialized() throws Exception {
|
||||
when(dbInitializer.isBareInit()).thenReturn(false);
|
||||
|
||||
stackLoader.start();
|
||||
|
||||
verify(stackDao, never()).update(any());
|
||||
verify(stackDao, never()).create(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dtoShouldBeSerialized() throws Exception {
|
||||
StackDto stackDtoDescriptor = newDto(StackDto.class).withName("nameWorkspaceConfig");
|
||||
StackComponentDto stackComponentDto =
|
||||
newDto(StackComponentDto.class).withName("java").withVersion("1.8");
|
||||
stackDtoDescriptor.setComponents(Collections.singletonList(stackComponentDto));
|
||||
stackDtoDescriptor.setTags(Arrays.asList("some teg1", "some teg2"));
|
||||
stackDtoDescriptor.setDescription("description");
|
||||
stackDtoDescriptor.setId("someId");
|
||||
stackDtoDescriptor.setScope("scope");
|
||||
stackDtoDescriptor.setCreator("Created in Codenvy");
|
||||
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put("attribute1", "valute attribute1");
|
||||
Link link =
|
||||
newDto(Link.class)
|
||||
.withHref("some url")
|
||||
.withMethod("get")
|
||||
.withRel("someRel")
|
||||
.withConsumes("consumes")
|
||||
.withProduces("produces");
|
||||
|
||||
HashMap<String, List<String>> projectMap = new HashMap<>();
|
||||
projectMap.put("test", Arrays.asList("test", "test2"));
|
||||
|
||||
ProjectProblemDto projectProblem =
|
||||
newDto(ProjectProblemDto.class).withCode(100).withMessage("message");
|
||||
SourceStorageDto sourceStorageDto =
|
||||
newDto(SourceStorageDto.class)
|
||||
.withType("some type")
|
||||
.withParameters(attributes)
|
||||
.withLocation("location");
|
||||
|
||||
ProjectConfigDto projectConfigDto =
|
||||
newDto(ProjectConfigDto.class)
|
||||
.withName("project")
|
||||
.withPath("somePath")
|
||||
.withAttributes(projectMap)
|
||||
.withType("maven type")
|
||||
.withDescription("some project description")
|
||||
.withLinks(Collections.singletonList(link))
|
||||
.withMixins(Collections.singletonList("mixin time"))
|
||||
.withProblems(Collections.singletonList(projectProblem))
|
||||
.withSource(sourceStorageDto);
|
||||
|
||||
RecipeDto environmentRecipe =
|
||||
newDto(RecipeDto.class)
|
||||
.withContent("some content")
|
||||
.withContentType("some content type")
|
||||
.withType("someType");
|
||||
|
||||
Map<String, ServerConfigDto> servers = new HashMap<>();
|
||||
servers.put(
|
||||
"server1Ref",
|
||||
newDto(ServerConfigDto.class)
|
||||
.withPort("8080/tcp")
|
||||
.withProtocol("http")
|
||||
.withAttributes(singletonMap("key", "value")));
|
||||
Map<String, MachineConfigDto> machines = new HashMap<>();
|
||||
machines.put(
|
||||
"someMachineName",
|
||||
newDto(MachineConfigDto.class)
|
||||
.withInstallers(Arrays.asList("agent1", "agent2"))
|
||||
.withServers(servers)
|
||||
.withAttributes(singletonMap(MEMORY_LIMIT_ATTRIBUTE, "" + 512L * 1024L * 1024L)));
|
||||
|
||||
EnvironmentDto environmentDto =
|
||||
newDto(EnvironmentDto.class).withRecipe(environmentRecipe).withMachines(machines);
|
||||
|
||||
CommandDto commandDto =
|
||||
newDto(CommandDto.class)
|
||||
.withType("command type")
|
||||
.withName("command name")
|
||||
.withCommandLine("command line");
|
||||
|
||||
WorkspaceConfigDto workspaceConfigDto =
|
||||
newDto(WorkspaceConfigDto.class)
|
||||
.withName("SomeWorkspaceConfig")
|
||||
.withDescription("some workspace")
|
||||
.withLinks(Collections.singletonList(link))
|
||||
.withDefaultEnv("some Default Env name")
|
||||
.withProjects(Collections.singletonList(projectConfigDto))
|
||||
.withEnvironments(singletonMap("name", environmentDto))
|
||||
.withCommands(Collections.singletonList(commandDto));
|
||||
|
||||
stackDtoDescriptor.setWorkspaceConfig(workspaceConfigDto);
|
||||
Gson GSON = new GsonBuilder().create();
|
||||
|
||||
GSON.fromJson(stackDtoDescriptor.toString(), StackImpl.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,573 +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.stack;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_GET_STACK_BY_ID;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.LINK_REL_REMOVE_STACK;
|
||||
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.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
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 com.jayway.restassured.response.Response;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
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.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
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.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackComponentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackDto;
|
||||
import org.eclipse.che.api.workspace.shared.stack.Stack;
|
||||
import org.eclipse.che.api.workspace.shared.stack.StackComponent;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
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.everrest.core.impl.uri.UriBuilderImpl;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Test for {@link @StackService}
|
||||
*
|
||||
* @author Alexander Andrienko
|
||||
*/
|
||||
@Listeners(value = {EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class StackServiceTest {
|
||||
|
||||
private static final String STACK_ID = "java-default";
|
||||
private static final String NAME = "Java";
|
||||
private static final String DESCRIPTION = "Default Java Stack with JDK 8, Maven and Tomcat.";
|
||||
private static final String USER_ID = "che";
|
||||
private static final String CREATOR = USER_ID;
|
||||
private static final String FOREIGN_CREATOR = "foreign_creator";
|
||||
private static final String SCOPE = "general";
|
||||
|
||||
private static final String SOURCE_TYPE = "image";
|
||||
private static final String SOURCE_ORIGIN = "codenvy/ubuntu_jdk8";
|
||||
|
||||
private static final String COMPONENT_NAME = "Java";
|
||||
private static final String COMPONENT_VERSION = "1.8.0_45";
|
||||
|
||||
private static final String WORKSPACE_CONFIG_NAME = "default";
|
||||
private static final String DEF_ENVIRONMENT_NAME = "default";
|
||||
|
||||
private static final String COMMAND_NAME = "newMaven";
|
||||
private static final String COMMAND_TYPE = "mvn";
|
||||
private static final String COMMAND_LINE = "mvn clean install -f ${current.project.path}";
|
||||
|
||||
private static final String ENVIRONMENT_NAME = "default";
|
||||
|
||||
private static final String ICON_MEDIA_TYPE = "image/svg+xml";
|
||||
|
||||
private static final String SVG_ICON =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
||||
+ "<svg viewBox=\"0 0 200 200\" xmlns=\"http://www.w3.org/2000/svg\">\n"
|
||||
+ " <circle cx=\"100\" cy=\"100\" r=\"100\" fill=\"red\"/>\n"
|
||||
+ "</svg>";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static final ApiExceptionMapper MAPPER = new ApiExceptionMapper();
|
||||
|
||||
private List<String> tags = asList("java", "maven");
|
||||
private StackDto stackDto;
|
||||
private StackImpl stackImpl;
|
||||
private StackImpl foreignStack;
|
||||
private List<StackComponent> componentsImpl;
|
||||
private StackIcon stackIcon;
|
||||
|
||||
private List<StackComponentDto> componentsDto;
|
||||
|
||||
@Mock StackDao stackDao;
|
||||
|
||||
@Mock UriInfo uriInfo;
|
||||
|
||||
@Mock StackComponentImpl stackComponent;
|
||||
|
||||
@Mock StackValidator validator;
|
||||
|
||||
@InjectMocks StackService service;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
byte[] fileContent = STACK_ID.getBytes();
|
||||
stackIcon = new StackIcon(ICON_MEDIA_TYPE, "image/svg+xml", fileContent);
|
||||
componentsImpl = singletonList(new StackComponentImpl(COMPONENT_NAME, COMPONENT_VERSION));
|
||||
CommandImpl command = new CommandImpl(COMMAND_NAME, COMMAND_LINE, COMMAND_TYPE);
|
||||
EnvironmentImpl environment = new EnvironmentImpl(null, null);
|
||||
|
||||
WorkspaceConfigImpl workspaceConfig =
|
||||
WorkspaceConfigImpl.builder()
|
||||
.setName(WORKSPACE_CONFIG_NAME)
|
||||
.setDefaultEnv(DEF_ENVIRONMENT_NAME)
|
||||
.setCommands(singletonList(command))
|
||||
.setEnvironments(singletonMap(ENVIRONMENT_NAME, environment))
|
||||
.build();
|
||||
|
||||
StackComponentDto stackComponentDto =
|
||||
newDto(StackComponentDto.class).withName(COMPONENT_NAME).withVersion(COMPONENT_VERSION);
|
||||
componentsDto = singletonList(stackComponentDto);
|
||||
|
||||
stackDto =
|
||||
DtoFactory.getInstance()
|
||||
.createDto(StackDto.class)
|
||||
.withId(STACK_ID)
|
||||
.withName(NAME)
|
||||
.withDescription(DESCRIPTION)
|
||||
.withScope(SCOPE)
|
||||
.withCreator(CREATOR)
|
||||
.withTags(tags)
|
||||
.withComponents(componentsDto);
|
||||
|
||||
stackImpl =
|
||||
StackImpl.builder()
|
||||
.setId(STACK_ID)
|
||||
.setName(NAME)
|
||||
.setDescription(DESCRIPTION)
|
||||
.setScope(SCOPE)
|
||||
.setCreator(CREATOR)
|
||||
.setTags(tags)
|
||||
.setComponents(componentsImpl)
|
||||
.setWorkspaceConfig(workspaceConfig)
|
||||
.setStackIcon(stackIcon)
|
||||
.build();
|
||||
|
||||
foreignStack =
|
||||
StackImpl.builder()
|
||||
.setId(STACK_ID)
|
||||
.setName(NAME)
|
||||
.setDescription(DESCRIPTION)
|
||||
.setScope(SCOPE)
|
||||
.setCreator(FOREIGN_CREATOR)
|
||||
.setTags(tags)
|
||||
.setComponents(componentsImpl)
|
||||
.setWorkspaceConfig(workspaceConfig)
|
||||
.setStackIcon(stackIcon)
|
||||
.build();
|
||||
|
||||
lenient().when(uriInfo.getBaseUriBuilder()).thenReturn(new UriBuilderImpl());
|
||||
|
||||
final Field uriField = service.getClass().getSuperclass().getDeclaredField("uriInfo");
|
||||
uriField.setAccessible(true);
|
||||
uriField.set(service, uriInfo);
|
||||
}
|
||||
|
||||
/** Create stack */
|
||||
@Test
|
||||
public void newStackShouldBeCreatedForUser() throws ConflictException, ServerException {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType(APPLICATION_JSON)
|
||||
.body(stackDto)
|
||||
.when()
|
||||
.post(SECURE_PATH + "/stack");
|
||||
|
||||
assertEquals(response.getStatusCode(), 201);
|
||||
|
||||
verify(stackDao).create(any(StackImpl.class));
|
||||
|
||||
final StackDto stackDtoDescriptor = unwrapDto(response, StackDto.class);
|
||||
|
||||
assertEquals(stackDtoDescriptor.getName(), stackDto.getName());
|
||||
assertEquals(stackDtoDescriptor.getCreator(), USER_ID);
|
||||
assertEquals(stackDtoDescriptor.getDescription(), stackDto.getDescription());
|
||||
assertEquals(stackDtoDescriptor.getTags(), stackDto.getTags());
|
||||
|
||||
assertEquals(stackDtoDescriptor.getComponents(), stackDto.getComponents());
|
||||
|
||||
assertEquals(stackDtoDescriptor.getScope(), stackDto.getScope());
|
||||
|
||||
assertEquals(stackDtoDescriptor.getLinks().size(), 2);
|
||||
assertEquals(stackDtoDescriptor.getLinks().get(0).getRel(), LINK_REL_REMOVE_STACK);
|
||||
assertEquals(stackDtoDescriptor.getLinks().get(1).getRel(), LINK_REL_GET_STACK_BY_ID);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void shouldThrowBadRequestExceptionOnCreateStackWithEmptyBody() {
|
||||
// final Response response = given().auth()
|
||||
// .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
// .contentType(APPLICATION_JSON)
|
||||
// .when()
|
||||
// .post(SECURE_PATH + "/stack");
|
||||
//
|
||||
// assertEquals(response.getStatusCode(), 400);
|
||||
// assertEquals(unwrapDto(response, ServiceError.class).getMessage(), "Stack required");
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void shouldThrowBadRequestExceptionOnCreateStackWithEmptyName() {
|
||||
// StackComponentDto stackComponentDto =
|
||||
// newDto(StackComponentDto.class).withName("Java").withVersion("1.8.45");
|
||||
// StackDto stackDto = newDto(StackDto.class).withId(USER_ID)
|
||||
// .withDescription("")
|
||||
// .withScope("Simple java stack for generation
|
||||
// java projects")
|
||||
// .withTags(asList("java", "maven"))
|
||||
// .withCreator("che")
|
||||
//
|
||||
// .withComponents(singletonList(stackComponentDto))
|
||||
//
|
||||
// Response response = given().auth()
|
||||
// .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
// .contentType(APPLICATION_JSON)
|
||||
// .body(stackDto)
|
||||
// .when()
|
||||
// .post(SECURE_PATH + "/stack");
|
||||
//
|
||||
// assertEquals(response.getStatusCode(), 400);
|
||||
// assertEquals(unwrapDto(response, ServiceError.class).getMessage(), "Stack name
|
||||
// required");
|
||||
// }
|
||||
|
||||
/** Get stack by id */
|
||||
@Test
|
||||
public void stackByIdShouldBeReturned() throws NotFoundException, ServerException {
|
||||
when(stackDao.getById(STACK_ID)).thenReturn(stackImpl);
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack/" + STACK_ID);
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
StackDto result = unwrapDto(response, StackDto.class);
|
||||
assertEquals(result.getId(), stackImpl.getId());
|
||||
assertEquals(result.getName(), stackImpl.getName());
|
||||
assertEquals(result.getDescription(), stackImpl.getDescription());
|
||||
assertEquals(result.getScope(), stackImpl.getScope());
|
||||
assertEquals(result.getTags().get(0), stackImpl.getTags().get(0));
|
||||
assertEquals(result.getTags().get(1), stackImpl.getTags().get(1));
|
||||
assertEquals(
|
||||
result.getComponents().get(0).getName(), stackImpl.getComponents().get(0).getName());
|
||||
assertEquals(
|
||||
result.getComponents().get(0).getVersion(), stackImpl.getComponents().get(0).getVersion());
|
||||
assertEquals(result.getCreator(), stackImpl.getCreator());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stackShouldBeUpdated() throws NotFoundException, ServerException, ConflictException {
|
||||
final String updatedDescription = "some description";
|
||||
final String updatedScope = "advanced";
|
||||
StackDto updatedStackDto =
|
||||
DtoFactory.getInstance()
|
||||
.createDto(StackDto.class)
|
||||
.withId(STACK_ID)
|
||||
.withName(NAME)
|
||||
.withDescription(updatedDescription)
|
||||
.withScope(updatedScope)
|
||||
.withCreator(CREATOR)
|
||||
.withTags(tags)
|
||||
.withComponents(componentsDto);
|
||||
|
||||
StackImpl updateStack = new StackImpl(stackImpl);
|
||||
updateStack.setDescription(updatedDescription);
|
||||
updateStack.setScope(updatedScope);
|
||||
|
||||
when(stackDao.getById(STACK_ID)).thenReturn(stackImpl).thenReturn(updateStack);
|
||||
when(stackDao.update(any())).thenReturn(updateStack).thenReturn(updateStack);
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType(APPLICATION_JSON)
|
||||
.content(updatedStackDto)
|
||||
.when()
|
||||
.put(SECURE_PATH + "/stack/" + STACK_ID);
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
StackDto result = unwrapDto(response, StackDto.class);
|
||||
|
||||
assertEquals(result.getId(), updatedStackDto.getId());
|
||||
assertEquals(result.getName(), updatedStackDto.getName());
|
||||
assertEquals(result.getDescription(), updatedStackDto.getDescription());
|
||||
assertEquals(result.getScope(), updatedStackDto.getScope());
|
||||
assertEquals(result.getTags().get(0), updatedStackDto.getTags().get(0));
|
||||
assertEquals(result.getTags().get(1), updatedStackDto.getTags().get(1));
|
||||
assertEquals(
|
||||
result.getComponents().get(0).getName(), updatedStackDto.getComponents().get(0).getName());
|
||||
assertEquals(
|
||||
result.getComponents().get(0).getVersion(),
|
||||
updatedStackDto.getComponents().get(0).getVersion());
|
||||
assertEquals(result.getCreator(), updatedStackDto.getCreator());
|
||||
|
||||
verify(stackDao).update(any());
|
||||
verify(stackDao).getById(STACK_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void creatorShouldNotBeUpdated()
|
||||
throws ServerException, NotFoundException, ConflictException {
|
||||
StackDto updatedStackDto =
|
||||
DtoFactory.getInstance()
|
||||
.createDto(StackDto.class)
|
||||
.withId(STACK_ID)
|
||||
.withName(NAME)
|
||||
.withDescription(DESCRIPTION)
|
||||
.withScope(SCOPE)
|
||||
.withCreator("creator changed")
|
||||
.withTags(tags)
|
||||
.withComponents(componentsDto);
|
||||
|
||||
when(stackDao.getById(anyString())).thenReturn(foreignStack);
|
||||
when(stackDao.update(any())).thenReturn(foreignStack);
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType(APPLICATION_JSON)
|
||||
.content(updatedStackDto)
|
||||
.when()
|
||||
.put(SECURE_PATH + "/stack/" + STACK_ID);
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
StackDto result = unwrapDto(response, StackDto.class);
|
||||
|
||||
assertEquals(result.getId(), updatedStackDto.getId());
|
||||
assertEquals(result.getName(), updatedStackDto.getName());
|
||||
assertEquals(result.getDescription(), updatedStackDto.getDescription());
|
||||
assertEquals(result.getScope(), updatedStackDto.getScope());
|
||||
assertEquals(result.getTags().get(0), updatedStackDto.getTags().get(0));
|
||||
assertEquals(result.getTags().get(1), updatedStackDto.getTags().get(1));
|
||||
assertEquals(
|
||||
result.getComponents().get(0).getName(), updatedStackDto.getComponents().get(0).getName());
|
||||
assertEquals(
|
||||
result.getComponents().get(0).getVersion(),
|
||||
updatedStackDto.getComponents().get(0).getVersion());
|
||||
assertEquals(result.getCreator(), FOREIGN_CREATOR);
|
||||
|
||||
verify(stackDao).update(any());
|
||||
verify(stackDao).getById(STACK_ID);
|
||||
}
|
||||
|
||||
/** Delete stack */
|
||||
@Test
|
||||
public void stackShouldBeDeleted() throws ServerException, NotFoundException {
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/stack/" + STACK_ID);
|
||||
|
||||
verify(stackDao).remove(eq(STACK_ID));
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
}
|
||||
|
||||
/** Search stack by tags */
|
||||
@Test
|
||||
public void shouldReturnsAllStacksWhenListTagsIsEmpty() throws ServerException {
|
||||
StackImpl stack2 = new StackImpl(stackImpl);
|
||||
stack2.setTags(singletonList("subversion"));
|
||||
List<StackImpl> stacks = asList(stackImpl, stack2);
|
||||
when(stackDao.searchStacks(anyString(), nullable(List.class), anyInt(), anyInt()))
|
||||
.thenReturn(stacks);
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(stackDao).searchStacks(anyString(), nullable(List.class), anyInt(), anyInt());
|
||||
|
||||
List<StackDto> result = unwrapListDto(response, StackDto.class);
|
||||
assertEquals(result.size(), 2);
|
||||
assertEquals(result.get(0).getName(), stackImpl.getName());
|
||||
assertEquals(result.get(1).getName(), stack2.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnsStackByTagList() throws ServerException {
|
||||
StackImpl stack2 = new StackImpl(stackImpl);
|
||||
stack2.setTags(singletonList("Subversion"));
|
||||
when(stackDao.searchStacks(anyString(), eq(singletonList("Subversion")), anyInt(), anyInt()))
|
||||
.thenReturn(singletonList(stack2));
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack?tags=Subversion");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(stackDao).searchStacks(anyString(), eq(singletonList("Subversion")), anyInt(), anyInt());
|
||||
|
||||
List<StackDto> result = unwrapListDto(response, StackDto.class);
|
||||
assertEquals(result.size(), 1);
|
||||
assertEquals(result.get(0).getName(), stack2.getName());
|
||||
}
|
||||
|
||||
/** Get icon by stack id */
|
||||
@Test
|
||||
public void shouldReturnIconByStackId() throws NotFoundException, ServerException {
|
||||
when(stackDao.getById(stackImpl.getId())).thenReturn(stackImpl);
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack/" + stackImpl.getId() + "/icon");
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
|
||||
verify(stackDao).getById(stackImpl.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowNotFoundExceptionWhenIconStackWasNotFound()
|
||||
throws NotFoundException, ServerException {
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack/" + stackImpl.getId() + "/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 404);
|
||||
String expectedErrorMessage = format("Stack with id '%s' was not found.", STACK_ID);
|
||||
assertEquals(unwrapDto(response, ServiceError.class).getMessage(), expectedErrorMessage);
|
||||
verify(stackDao).getById(stackImpl.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowNotFoundExceptionWhenIconWasNotFound()
|
||||
throws NotFoundException, ServerException {
|
||||
StackImpl test = new StackImpl(stackImpl);
|
||||
test.setStackIcon(null);
|
||||
when(stackDao.getById(test.getId())).thenReturn(test);
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/stack/" + stackImpl.getId() + "/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 404);
|
||||
String expectedErrorMessage = format("Image for stack with id '%s' was not found.", STACK_ID);
|
||||
assertEquals(unwrapDto(response, ServiceError.class).getMessage(), expectedErrorMessage);
|
||||
verify(stackDao).getById(test.getId());
|
||||
}
|
||||
|
||||
/** Delete icon by stack id */
|
||||
@Test
|
||||
public void stackIconShouldBeDeletedForUserOwner()
|
||||
throws NotFoundException, ConflictException, ServerException {
|
||||
when(stackDao.getById(stackImpl.getId())).thenReturn(stackImpl);
|
||||
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/stack/" + stackImpl.getId() + "/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(stackDao).getById(stackImpl.getId());
|
||||
verify(stackDao).update(stackImpl);
|
||||
}
|
||||
|
||||
/** Update stack icon */
|
||||
@Test
|
||||
public void stackIconShouldBeUploadedForUserOwner()
|
||||
throws NotFoundException, ConflictException, ServerException, URISyntaxException {
|
||||
when(stackDao.getById(stackImpl.getId())).thenReturn(stackImpl);
|
||||
|
||||
checkUploadIcon(stackImpl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void foreignStackIconShouldBeUploadedForUser()
|
||||
throws NotFoundException, ConflictException, ServerException {
|
||||
when(stackDao.getById(foreignStack.getId())).thenReturn(foreignStack);
|
||||
|
||||
checkUploadIcon(foreignStack);
|
||||
}
|
||||
|
||||
private void checkUploadIcon(Stack stack)
|
||||
throws NotFoundException, ServerException, ConflictException {
|
||||
Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.multiPart("type-java.svg", SVG_ICON, "image/svg+xml")
|
||||
.contentType(MULTIPART_FORM_DATA)
|
||||
.post(SECURE_PATH + "/stack/" + stackImpl.getId() + "/icon");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(stackDao).getById(foreignStack.getId());
|
||||
verify(stackDao).update(any());
|
||||
}
|
||||
|
||||
private static <T> T unwrapDto(Response response, Class<T> dtoClass) {
|
||||
return DtoFactory.getInstance().createDtoFromJson(response.body().print(), dtoClass);
|
||||
}
|
||||
|
||||
private static <T> List<T> unwrapListDto(Response response, Class<T> dtoClass) {
|
||||
return DtoFactory.getInstance().createListDtoFromJson(response.body().print(), dtoClass);
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
@Override
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(new SubjectImpl("user", USER_ID, "token", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,125 +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.stack;
|
||||
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceValidator;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackComponentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.stack.StackDto;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Test for {@link StackValidator}
|
||||
*
|
||||
* @author Mihail Kuznyetsov
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class StackValidatorTest {
|
||||
|
||||
@InjectMocks private StackValidator validator;
|
||||
|
||||
@Mock private WorkspaceValidator wsValidator;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
doNothing().when(wsValidator).validateConfig(any(WorkspaceConfigDto.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldcheck() throws Exception {
|
||||
validator.check(createStack());
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = BadRequestException.class,
|
||||
expectedExceptionsMessageRegExp = "Required non-null stack")
|
||||
public void shouldNotValidateIfStackIsNull() throws Exception {
|
||||
validator.check(null);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = BadRequestException.class,
|
||||
expectedExceptionsMessageRegExp = "Required non-null and non-empty stack name")
|
||||
public void shouldNotValidateIfStackNameIsNull() throws Exception {
|
||||
validator.check(createStack().withName(null));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = BadRequestException.class,
|
||||
expectedExceptionsMessageRegExp = "Required non-null and non-empty stack name")
|
||||
public void shouldNotValidateIfStackNameIsEmpty() throws Exception {
|
||||
validator.check(createStack().withName(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldValidateIfStackScopeIsGeneral() throws Exception {
|
||||
validator.check(createStack().withScope("general"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldValidateIfStackScopeIsAdvanced() throws Exception {
|
||||
validator.check(createStack().withScope("advanced"));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = BadRequestException.class,
|
||||
expectedExceptionsMessageRegExp = "Required non-null scope value: 'general' or 'advanced'")
|
||||
public void shouldNotValidateIfStackScopeIsNull() throws Exception {
|
||||
validator.check(createStack().withScope(null));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = BadRequestException.class,
|
||||
expectedExceptionsMessageRegExp = "Required non-null scope value: 'general' or 'advanced'")
|
||||
public void shouldNotValidateIfStackScopeIsNotGeneralOrAdvanced() throws Exception {
|
||||
validator.check(createStack().withScope("not-valid"));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = BadRequestException.class,
|
||||
expectedExceptionsMessageRegExp = "Workspace config required")
|
||||
public void shouldValidateIfSourceIsStackSourceAndWorkspaceConfigIsNull() throws Exception {
|
||||
validator.check(createStack().withWorkspaceConfig(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotcheck() throws Exception {
|
||||
validator.check(createStack());
|
||||
}
|
||||
|
||||
private static StackDto createStack() {
|
||||
return newDto(StackDto.class)
|
||||
.withId("stack123")
|
||||
.withName("Name")
|
||||
.withDescription("Description")
|
||||
.withScope("general")
|
||||
.withCreator("user123")
|
||||
.withTags(new ArrayList<>(Collections.singletonList("latest")))
|
||||
.withWorkspaceConfig(newDto(WorkspaceConfigDto.class))
|
||||
.withComponents(
|
||||
new ArrayList<>(
|
||||
Collections.singletonList(
|
||||
newDto(StackComponentDto.class).withName("maven").withVersion("3.3.1"))));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,367 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": "java-default",
|
||||
"creator": "ide",
|
||||
"name": "Java",
|
||||
"description": "Default Java Stack with JDK 8, Maven and Tomcat.",
|
||||
"scope": "general",
|
||||
"tags": [
|
||||
"Java",
|
||||
"JDK",
|
||||
"Maven",
|
||||
"Tomcat",
|
||||
"Subversion",
|
||||
"Ubuntu",
|
||||
"Git"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "JDK",
|
||||
"version": "1.8.0_45"
|
||||
},
|
||||
{
|
||||
"name": "Maven",
|
||||
"version": "3.2.2"
|
||||
},
|
||||
{
|
||||
"name": "Tomcat",
|
||||
"version": "8.0.24"
|
||||
}
|
||||
],
|
||||
"workspaceConfig": {
|
||||
"environments": {
|
||||
"default" : {
|
||||
"machines": {
|
||||
"devmachine": {
|
||||
"installers": [
|
||||
"org.eclipse.che.ws-agent"
|
||||
],
|
||||
"attributes" : {
|
||||
"memoryLimitBytes": "2147483648"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recipe": {
|
||||
"location": "codenvy/ubuntu_jdk8",
|
||||
"type": "dockerimage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null,
|
||||
"commands": [
|
||||
{
|
||||
"commandLine": "mvn clean install -f ${current.project.path}",
|
||||
"name": "newMaven",
|
||||
"type": "mvn"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stackIcon" : {
|
||||
"name": "type-java.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "node-default",
|
||||
"creator": "ide",
|
||||
"name": "Node",
|
||||
"description": "Default Node Stack with Node 0.12.",
|
||||
"scope": "general",
|
||||
"tags": [
|
||||
"Ubuntu",
|
||||
"Git",
|
||||
"Node.JS",
|
||||
"NPM",
|
||||
"Gulp",
|
||||
"Bower",
|
||||
"Grunt",
|
||||
"Yeoman",
|
||||
"Angular",
|
||||
"Karma"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "Node.JS",
|
||||
"version": "0.12.9"
|
||||
},
|
||||
{
|
||||
"name": "NPM",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Gulp",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Bower",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Grunt",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Yeoman",
|
||||
"version": "---"
|
||||
}
|
||||
],
|
||||
"workspaceConfig": {
|
||||
"environments": {
|
||||
"default" : {
|
||||
"machines": {
|
||||
"devmachine": {
|
||||
"installers": [
|
||||
"org.eclipse.che.ws-agent"
|
||||
],
|
||||
"attributes" : {
|
||||
"memoryLimitBytes": "2147483648"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recipe": {
|
||||
"location": "https://raw.githubusercontent.com/eclipse/che/master/Dockerfile",
|
||||
"type": "dockerfile",
|
||||
"contentType": "text/x-dockerfile"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null,
|
||||
"commands": [
|
||||
{
|
||||
"commandLine": "mvn clean install -f ${current.project.path}",
|
||||
"name": "newMaven",
|
||||
"type": "mvn"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "node-default",
|
||||
"creator": "ide",
|
||||
"name": "Node",
|
||||
"description": "Default Node Stack with Node 0.12.",
|
||||
"scope": "general",
|
||||
"tags": [
|
||||
"Ubuntu",
|
||||
"Git",
|
||||
"Node.JS",
|
||||
"NPM",
|
||||
"Gulp",
|
||||
"Bower",
|
||||
"Grunt",
|
||||
"Yeoman",
|
||||
"Angular",
|
||||
"Karma"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "Node.JS",
|
||||
"version": "0.12.9"
|
||||
},
|
||||
{
|
||||
"name": "NPM",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Gulp",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Bower",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Grunt",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Yeoman",
|
||||
"version": "---"
|
||||
}
|
||||
],
|
||||
"workspaceConfig": {
|
||||
"environments": {
|
||||
"default" : {
|
||||
"machines": {
|
||||
"devmachine": {
|
||||
"installers": [
|
||||
"org.eclipse.che.ws-agent"
|
||||
],
|
||||
"attributes" : {
|
||||
"memoryLimitBytes": "2147483648"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recipe": {
|
||||
"content": "FROM codenvy/ubuntu_jdk8",
|
||||
"type": "dockerfile",
|
||||
"contentType": "text/x-dockerfile"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null,
|
||||
"commands": [
|
||||
{
|
||||
"commandLine": "mvn clean install -f ${current.project.path}",
|
||||
"name": "newMaven",
|
||||
"type": "mvn"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "compose-location",
|
||||
"creator": "ide",
|
||||
"name": "Node",
|
||||
"description": "Default Node Stack with Node 0.12.",
|
||||
"scope": "general",
|
||||
"tags": [
|
||||
"Ubuntu",
|
||||
"Git",
|
||||
"Node.JS",
|
||||
"NPM",
|
||||
"Gulp",
|
||||
"Bower",
|
||||
"Grunt",
|
||||
"Yeoman",
|
||||
"Angular",
|
||||
"Karma"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "Node.JS",
|
||||
"version": "0.12.9"
|
||||
},
|
||||
{
|
||||
"name": "NPM",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Gulp",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Bower",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Grunt",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Yeoman",
|
||||
"version": "---"
|
||||
}
|
||||
],
|
||||
"workspaceConfig": {
|
||||
"environments": {
|
||||
"default" : {
|
||||
"machines": {
|
||||
"devmachine": {
|
||||
"installers": [
|
||||
"org.eclipse.che.ws-agent"
|
||||
],
|
||||
"attributes" : {
|
||||
"memoryLimitBytes": "2147483648"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recipe": {
|
||||
"location": "https://raw.githubusercontent.com/eclipse/che/master/Dockerfile",
|
||||
"type": "compose",
|
||||
"contentType": "application/x-yaml"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null,
|
||||
"commands": [
|
||||
{
|
||||
"commandLine": "mvn clean install -f ${current.project.path}",
|
||||
"name": "newMaven",
|
||||
"type": "mvn"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "compose-content",
|
||||
"creator": "ide",
|
||||
"name": "Node",
|
||||
"description": "Default Node Stack with Node 0.12.",
|
||||
"scope": "general",
|
||||
"tags": [
|
||||
"Ubuntu",
|
||||
"Git",
|
||||
"Node.JS",
|
||||
"NPM",
|
||||
"Gulp",
|
||||
"Bower",
|
||||
"Grunt",
|
||||
"Yeoman",
|
||||
"Angular",
|
||||
"Karma"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "Node.JS",
|
||||
"version": "0.12.9"
|
||||
},
|
||||
{
|
||||
"name": "NPM",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Gulp",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Bower",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Grunt",
|
||||
"version": "---"
|
||||
},
|
||||
{
|
||||
"name": "Yeoman",
|
||||
"version": "---"
|
||||
}
|
||||
],
|
||||
"workspaceConfig": {
|
||||
"environments": {
|
||||
"default" : {
|
||||
"machines": {
|
||||
"devmachine": {
|
||||
"installers": [
|
||||
"org.eclipse.che.ws-agent"
|
||||
]
|
||||
}
|
||||
},
|
||||
"recipe": {
|
||||
"content": "service:\n devmachine:\n image: codenvy/ubuntu_jdk8\n mem_limit: 2147483648",
|
||||
"type": "compose",
|
||||
"contentType": "application/x-yaml"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null,
|
||||
"commands": [
|
||||
{
|
||||
"commandLine": "mvn clean install -f ${current.project.path}",
|
||||
"name": "newMaven",
|
||||
"type": "mvn"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
--
|
||||
-- Copyright (c) 2012-2019 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
|
||||
--
|
||||
|
||||
DROP TABLE stack_components;
|
||||
DROP TABLE stack_tags;
|
||||
DROP TABLE stack;
|
||||
|
|
@ -95,7 +95,6 @@ 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.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
|
|
@ -193,7 +192,6 @@ public class CascadeRemovalTest {
|
|||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
StackImpl.class,
|
||||
CommandImpl.class,
|
||||
RecipeImpl.class,
|
||||
SshPairImpl.class,
|
||||
|
|
|
|||
|
|
@ -47,9 +47,6 @@ import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
|
|||
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.api.workspace.server.model.impl.stack.StackComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesMachineImpl;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesRuntimeState;
|
||||
|
|
@ -223,24 +220,6 @@ public final class TestObjectsFactory {
|
|||
return new SshPairImpl(owner, service, name, "public-key", "private-key");
|
||||
}
|
||||
|
||||
public static StackImpl createStack(String id, String name) {
|
||||
return StackImpl.builder()
|
||||
.setId(id)
|
||||
.setName(name)
|
||||
.setCreator("user123")
|
||||
.setDescription(id + "-description")
|
||||
.setScope(id + "-scope")
|
||||
.setWorkspaceConfig(createWorkspaceConfig("test"))
|
||||
.setTags(asList(id + "-tag1", id + "-tag2"))
|
||||
.setComponents(
|
||||
asList(
|
||||
new StackComponentImpl(id + "-component1", id + "-component1-version"),
|
||||
new StackComponentImpl(id + "-component2", id + "-component2-version")))
|
||||
.setStackIcon(
|
||||
new StackIcon(id + "-icon", id + "-media-type", "0x1234567890abcdef".getBytes()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static KubernetesRuntimeState createK8sRuntimeState(String workspaceId) {
|
||||
return new KubernetesRuntimeState(
|
||||
new RuntimeIdentityImpl(workspaceId, "envName", "ownerId"),
|
||||
|
|
|
|||
|
|
@ -303,11 +303,7 @@
|
|||
<port>jdbc.port:3306</port>
|
||||
</ports>
|
||||
<wait>
|
||||
<tcp>
|
||||
<ports>
|
||||
<port>3306</port>
|
||||
</ports>
|
||||
</tcp>
|
||||
<log>ready for connections</log>
|
||||
<time>60000</time>
|
||||
</wait>
|
||||
<restartPolicy>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ import org.eclipse.che.api.workspace.activity.WorkspaceActivity;
|
|||
import org.eclipse.che.api.workspace.activity.WorkspaceActivityDao;
|
||||
import org.eclipse.che.api.workspace.activity.WorkspaceExpiration;
|
||||
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaStackDao;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
|
||||
|
|
@ -65,8 +64,6 @@ 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.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.commons.test.db.PersistTestModuleBuilder;
|
||||
|
|
@ -136,7 +133,6 @@ public class MySqlTckModule extends TckModule {
|
|||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
StackImpl.class,
|
||||
CommandImpl.class,
|
||||
SshPairImpl.class,
|
||||
InstallerImpl.class,
|
||||
|
|
@ -204,10 +200,8 @@ public class MySqlTckModule extends TckModule {
|
|||
|
||||
// workspace
|
||||
bind(WorkspaceDao.class).to(JpaWorkspaceDao.class);
|
||||
bind(StackDao.class).to(JpaStackDao.class);
|
||||
bind(WorkspaceActivityDao.class).to(JpaWorkspaceActivityDao.class);
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {}).toInstance(new WorkspaceRepository());
|
||||
bind(new TypeLiteral<TckRepository<StackImpl>>() {}).toInstance(new StackRepository());
|
||||
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceExpiration>>() {})
|
||||
.toInstance(new JpaTckRepository<>(WorkspaceExpiration.class));
|
||||
|
|
@ -331,18 +325,4 @@ public class MySqlTckModule extends TckModule {
|
|||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StackRepository extends JpaTckRepository<StackImpl> {
|
||||
public StackRepository() {
|
||||
super(StackImpl.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAll(Collection<? extends StackImpl> entities) throws TckRepositoryException {
|
||||
for (StackImpl stack : entities) {
|
||||
stack.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ import org.eclipse.che.api.workspace.activity.WorkspaceActivity;
|
|||
import org.eclipse.che.api.workspace.activity.WorkspaceActivityDao;
|
||||
import org.eclipse.che.api.workspace.activity.WorkspaceExpiration;
|
||||
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaStackDao;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
|
||||
|
|
@ -65,8 +64,6 @@ 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.stack.StackImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.commons.test.db.PersistTestModuleBuilder;
|
||||
|
|
@ -133,7 +130,6 @@ public class PostgreSqlTckModule extends TckModule {
|
|||
MachineConfigImpl.class,
|
||||
SourceStorageImpl.class,
|
||||
ServerConfigImpl.class,
|
||||
StackImpl.class,
|
||||
CommandImpl.class,
|
||||
SshPairImpl.class,
|
||||
InstallerImpl.class,
|
||||
|
|
@ -199,10 +195,8 @@ public class PostgreSqlTckModule extends TckModule {
|
|||
|
||||
// workspace
|
||||
bind(WorkspaceDao.class).to(JpaWorkspaceDao.class);
|
||||
bind(StackDao.class).to(JpaStackDao.class);
|
||||
bind(WorkspaceActivityDao.class).to(JpaWorkspaceActivityDao.class);
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceImpl>>() {}).toInstance(new WorkspaceRepository());
|
||||
bind(new TypeLiteral<TckRepository<StackImpl>>() {}).toInstance(new StackRepository());
|
||||
bind(new TypeLiteral<TckRepository<WorkspaceExpiration>>() {})
|
||||
.toInstance(new JpaTckRepository<>(WorkspaceExpiration.class));
|
||||
|
||||
|
|
@ -321,19 +315,4 @@ public class PostgreSqlTckModule extends TckModule {
|
|||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StackRepository extends JpaTckRepository<StackImpl> {
|
||||
|
||||
public StackRepository() {
|
||||
super(StackImpl.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAll(Collection<? extends StackImpl> entities) throws TckRepositoryException {
|
||||
for (StackImpl stack : entities) {
|
||||
stack.getWorkspaceConfig().getProjects().forEach(ProjectConfigImpl::prePersistAttributes);
|
||||
}
|
||||
super.createAll(entities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue