CHE-1790: Consolidate databases
parent
4ba7ffd2ae
commit
d5fe8aed73
|
|
@ -608,7 +608,7 @@ call_catalina () {
|
|||
|
||||
### Cannot add this in setenv.sh.
|
||||
### We do the port mapping here, and this gets inserted into server.xml when tomcat boots
|
||||
export JAVA_OPTS="${JAVA_OPTS} -Dport.http=${CHE_PORT} -Dche.home=${CHE_HOME}"
|
||||
export JAVA_OPTS="${JAVA_OPTS} -Dport.http=${CHE_PORT} -Dche.home=${CHE_HOME} -Dh2.baseDir=${CHE_HOME}/db/"
|
||||
export SERVER_PORT=${CHE_PORT}
|
||||
|
||||
# Launch the Che application server, passing in command line parameters
|
||||
|
|
|
|||
|
|
@ -46,6 +46,14 @@
|
|||
description="User database that can be updated and saved"
|
||||
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
|
||||
pathname="conf/tomcat-users.xml" /-->
|
||||
|
||||
<Resource name="che" auth="Container"
|
||||
type="javax.sql.DataSource"
|
||||
driverClassName="org.h2.Driver"
|
||||
url="jdbc:h2:che"
|
||||
username="" password=""
|
||||
maxTotal="8"
|
||||
maxIdle="4"/>
|
||||
</GlobalNamingResources>
|
||||
|
||||
<!-- A "Service" is a collection of one or more "Connectors" that share
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@
|
|||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-servlet</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
|
@ -66,6 +70,14 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc-vendor-h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-machine</artifactId>
|
||||
|
|
@ -82,6 +94,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-ssh</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-ssh-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-user</artifactId>
|
||||
|
|
@ -126,6 +142,10 @@
|
|||
<groupId>org.eclipse.che.plugin</groupId>
|
||||
<artifactId>che-plugin-ssh-machine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>eclipselink</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-core</artifactId>
|
||||
|
|
@ -148,6 +168,26 @@
|
|||
<artifactId>tomcat-catalina</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
|
|
|
|||
|
|
@ -13,14 +13,25 @@ package org.eclipse.che.api.deploy;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import com.google.inject.name.Names;
|
||||
import com.google.inject.persist.jpa.JpaPersistModule;
|
||||
|
||||
import org.eclipse.che.api.agent.server.launcher.AgentLauncher;
|
||||
import org.eclipse.che.api.core.rest.CheJsonProvider;
|
||||
import org.eclipse.che.api.core.rest.MessageBodyAdapter;
|
||||
import org.eclipse.che.api.core.rest.MessageBodyAdapterInterceptor;
|
||||
import org.eclipse.che.account.api.AccountModule;
|
||||
import org.eclipse.che.api.core.jdbc.jpa.eclipselink.EntityListenerInjectionManagerInitializer;
|
||||
import org.eclipse.che.api.core.jdbc.jpa.guice.JpaInitializer;
|
||||
import org.eclipse.che.api.machine.server.jpa.MachineJpaModule;
|
||||
import org.eclipse.che.api.machine.shared.Constants;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceConfigMessageBodyAdapter;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceMessageBodyAdapter;
|
||||
import org.eclipse.che.api.ssh.server.jpa.SshJpaModule;
|
||||
import org.eclipse.che.api.user.server.CheUserCreator;
|
||||
import org.eclipse.che.api.user.server.TokenValidator;
|
||||
|
||||
import org.eclipse.che.api.user.server.jpa.UserJpaModule;
|
||||
import org.eclipse.che.api.workspace.server.jpa.WorkspaceJpaModule;
|
||||
import org.eclipse.che.api.workspace.server.stack.StackMessageBodyAdapter;
|
||||
import org.eclipse.che.inject.DynaModule;
|
||||
|
||||
|
|
@ -32,6 +43,19 @@ import static org.eclipse.che.inject.Matchers.names;
|
|||
public class WsMasterModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
install(new JpaPersistModule("main"));
|
||||
bind(CheUserCreator.class);
|
||||
bind(JpaInitializer.class).asEagerSingleton();
|
||||
bind(EntityListenerInjectionManagerInitializer.class).asEagerSingleton();
|
||||
install(new UserJpaModule());
|
||||
install(new SshJpaModule());
|
||||
install(new WorkspaceJpaModule());
|
||||
install(new AccountModule());
|
||||
install(new MachineJpaModule());
|
||||
bind(TokenValidator.class).to(org.eclipse.che.api.local.DummyTokenValidator.class);
|
||||
bind(org.eclipse.che.api.local.LocalDataMigrator.class).asEagerSingleton();
|
||||
|
||||
bind(org.eclipse.che.api.core.rest.ApiInfoService.class);
|
||||
bind(org.eclipse.che.api.project.server.template.ProjectTemplateDescriptionLoader.class).asEagerSingleton();
|
||||
bind(org.eclipse.che.api.project.server.template.ProjectTemplateRegistry.class);
|
||||
|
|
@ -99,7 +123,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
install(new org.eclipse.che.api.core.util.FileCleaner.FileCleanerModule());
|
||||
install(new org.eclipse.che.plugin.docker.machine.local.LocalDockerModule());
|
||||
install(new org.eclipse.che.api.machine.server.MachineModule());
|
||||
install(new org.eclipse.che.api.local.LocalInfrastructureModule());
|
||||
install(new org.eclipse.che.plugin.docker.machine.ext.DockerExtServerModule());
|
||||
install(new org.eclipse.che.plugin.docker.machine.ext.DockerTerminalModule());
|
||||
install(new org.eclipse.che.swagger.deploy.DocsModule());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0">
|
||||
<persistence-unit name="main" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
||||
<non-jta-data-source>java:/comp/env/jdbc/che</non-jta-data-source>
|
||||
|
||||
<class>org.eclipse.che.account.spi.AccountImpl</class>
|
||||
<class>org.eclipse.che.api.user.server.model.impl.UserImpl</class>
|
||||
<class>org.eclipse.che.api.user.server.model.impl.ProfileImpl</class>
|
||||
<class>org.eclipse.che.api.user.server.jpa.PreferenceEntity</class>
|
||||
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.EnvironmentRecipeImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ExtendedMachineImpl</class>
|
||||
<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.ServerConf2Impl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.machine.server.model.impl.CommandImpl</class>
|
||||
<class>org.eclipse.che.api.machine.server.model.impl.MachineSourceImpl</class>
|
||||
<class>org.eclipse.che.api.machine.server.model.impl.SnapshotImpl</class>
|
||||
<class>org.eclipse.che.api.machine.server.recipe.RecipeImpl</class>
|
||||
|
||||
<class>org.eclipse.che.api.ssh.server.model.impl.SshPairImpl</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="eclipselink.exception-handler" value="org.eclipse.che.api.core.h2.jdbc.jpa.eclipselink.H2ExceptionHandler"/>
|
||||
<property name="eclipselink.target-server" value="None"/>
|
||||
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
|
||||
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
|
||||
<property name="eclipselink.logging.logger" value="DefaultLogger"/>
|
||||
<property name="eclipselink.logging.level" value="SEVERE"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
|
@ -13,4 +13,8 @@
|
|||
-->
|
||||
<Context allowCasualMultipartParsing="true">
|
||||
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve"/>
|
||||
</Context>
|
||||
|
||||
<ResourceLink global="che"
|
||||
name="jdbc/che"
|
||||
type="javax.sql.DataSource"/>
|
||||
</Context>
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ workspace.runtime.auto_snapshot=true
|
|||
workspace.runtime.auto_restore=true
|
||||
|
||||
# Reserved user names
|
||||
user.reserved_names=
|
||||
che.account.reserved_names=
|
||||
|
||||
# java opts for dev machine
|
||||
che.machine.java_opts=-Xms256m -Xmx2048m -Djava.security.egd=file:/dev/./urandom
|
||||
|
|
|
|||
|
|
@ -68,4 +68,10 @@
|
|||
<role-name>developer</role-name>
|
||||
</security-role>
|
||||
|
||||
<resource-ref>
|
||||
<res-ref-name>jdbc/che</res-ref-name>
|
||||
<res-type>javax.sql.DataSource</res-type>
|
||||
<res-auth>Container</res-auth>
|
||||
</resource-ref>
|
||||
|
||||
</web-app>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
|
||||
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl;
|
||||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
|
||||
import org.eclipse.che.api.machine.server.model.impl.SnapshotImpl;
|
||||
import org.eclipse.che.api.machine.server.recipe.RecipeImpl;
|
||||
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
|
||||
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.model.impl.stack.StackSourceImpl;
|
||||
import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* Defines method for creating tests object instances.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public final class TestObjectsFactory {
|
||||
|
||||
public static UserImpl createUser(String id) {
|
||||
return new UserImpl(id,
|
||||
id + "@eclipse.org",
|
||||
id + "_name",
|
||||
"password",
|
||||
asList(id + "_alias1", id + "_alias2"));
|
||||
}
|
||||
|
||||
public static ProfileImpl createProfile(String userId) {
|
||||
return new ProfileImpl(userId, new HashMap<>(ImmutableMap.of("attribute1", "value1",
|
||||
"attribute2", "value2",
|
||||
"attribute3", "value3")));
|
||||
}
|
||||
|
||||
public static Map<String, String> createPreferences() {
|
||||
return new HashMap<>(ImmutableMap.of("preference1", "value1",
|
||||
"preference2", "value2",
|
||||
"preference3", "value3"));
|
||||
}
|
||||
|
||||
public static WorkspaceConfigImpl createWorkspaceConfig(String id) {
|
||||
return new WorkspaceConfigImpl(id + "_name",
|
||||
id + "description",
|
||||
"default-env",
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
public static WorkspaceImpl createWorkspace(String id, Account account) {
|
||||
return new WorkspaceImpl(id, account, createWorkspaceConfig(id));
|
||||
}
|
||||
|
||||
public static SshPairImpl createSshPair(String owner, String service, String name) {
|
||||
return new SshPairImpl(owner, service, name, "public-key", "private-key");
|
||||
}
|
||||
|
||||
public static FactoryImpl createFactory(String id, String creator) {
|
||||
return new FactoryImpl(id,
|
||||
id + "-name",
|
||||
"4.0",
|
||||
createWorkspaceConfig(id),
|
||||
new AuthorImpl(creator, System.currentTimeMillis()),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
public static SnapshotImpl createSnapshot(String snapshotId, String workspaceId) {
|
||||
return new SnapshotImpl(snapshotId,
|
||||
"type",
|
||||
null,
|
||||
System.currentTimeMillis(),
|
||||
workspaceId,
|
||||
snapshotId + "_description",
|
||||
true,
|
||||
"dev-machine",
|
||||
snapshotId + "env-name");
|
||||
}
|
||||
|
||||
public static RecipeImpl createRecipe(String id) {
|
||||
return new RecipeImpl(id,
|
||||
"recipe-name-" + id,
|
||||
"recipe-creator",
|
||||
"recipe-type",
|
||||
"recipe-script",
|
||||
asList("recipe-tag1", "recipe-tag2"),
|
||||
"recipe-description");
|
||||
}
|
||||
|
||||
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")))
|
||||
.setSource(new StackSourceImpl(id + "-type", id + "-origin"))
|
||||
.setStackIcon(new StackIcon(id + "-icon",
|
||||
id + "-media-type",
|
||||
"0x1234567890abcdef".getBytes()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private TestObjectsFactory() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.jdbc.jpa;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Stage;
|
||||
import com.google.inject.persist.jpa.JpaPersistModule;
|
||||
|
||||
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.jdbc.jpa.eclipselink.EntityListenerInjectionManagerInitializer;
|
||||
import org.eclipse.che.api.core.jdbc.jpa.guice.JpaInitializer;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.core.notification.EventSubscriber;
|
||||
import org.eclipse.che.api.factory.server.jpa.FactoryJpaModule;
|
||||
import org.eclipse.che.api.factory.server.jpa.JpaFactoryDao.RemoveFactoriesBeforeUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
|
||||
import org.eclipse.che.api.factory.server.spi.FactoryDao;
|
||||
import org.eclipse.che.api.machine.server.jpa.MachineJpaModule;
|
||||
import org.eclipse.che.api.machine.server.model.impl.SnapshotImpl;
|
||||
import org.eclipse.che.api.machine.server.spi.SnapshotDao;
|
||||
import org.eclipse.che.api.ssh.server.jpa.JpaSshDao.RemoveSshKeysBeforeUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.ssh.server.jpa.SshJpaModule;
|
||||
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
|
||||
import org.eclipse.che.api.ssh.server.spi.SshDao;
|
||||
import org.eclipse.che.api.user.server.jpa.JpaPreferenceDao.RemovePreferencesBeforeUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.user.server.jpa.JpaProfileDao.RemoveProfileBeforeUserRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.user.server.jpa.UserJpaModule;
|
||||
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.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.ProfileDao;
|
||||
import org.eclipse.che.api.user.server.spi.UserDao;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao.RemoveSnapshotsBeforeWorkspaceRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao.RemoveWorkspaceBeforeAccountRemovedEventSubscriber;
|
||||
import org.eclipse.che.api.workspace.server.jpa.WorkspaceJpaModule;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.inject.lifecycle.InitModule;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createFactory;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createPreferences;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createProfile;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createSnapshot;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createSshPair;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createUser;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createWorkspace;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests top-level entities cascade removals.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class JpaEntitiesCascadeRemovalTest {
|
||||
|
||||
private Injector injector;
|
||||
private EventService eventService;
|
||||
private PreferenceDao preferenceDao;
|
||||
private UserDao userDao;
|
||||
private ProfileDao profileDao;
|
||||
private WorkspaceDao workspaceDao;
|
||||
private SnapshotDao snapshotDao;
|
||||
private SshDao sshDao;
|
||||
private FactoryDao factoryDao;
|
||||
|
||||
/** User is a root of dependency tree. */
|
||||
private UserImpl user;
|
||||
|
||||
/** Profile depends on user. */
|
||||
private ProfileImpl profile;
|
||||
|
||||
/** Preferences depend on user. */
|
||||
private Map<String, String> preferences;
|
||||
|
||||
/** Workspaces depend on user. */
|
||||
private WorkspaceImpl workspace1;
|
||||
private WorkspaceImpl workspace2;
|
||||
|
||||
/** SshPairs depend on user. */
|
||||
private SshPairImpl sshPair1;
|
||||
private SshPairImpl sshPair2;
|
||||
|
||||
/** Factories depend on user. */
|
||||
private FactoryImpl factory1;
|
||||
private FactoryImpl factory2;
|
||||
|
||||
/** Snapshots depend on workspace. */
|
||||
private SnapshotImpl snapshot1;
|
||||
private SnapshotImpl snapshot2;
|
||||
private SnapshotImpl snapshot3;
|
||||
private SnapshotImpl snapshot4;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
injector = Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(EventService.class).in(Singleton.class);
|
||||
|
||||
bind(JpaInitializer.class).asEagerSingleton();
|
||||
bind(EntityListenerInjectionManagerInitializer.class).asEagerSingleton();
|
||||
install(new InitModule(PostConstruct.class));
|
||||
install(new JpaPersistModule("test"));
|
||||
install(new UserJpaModule());
|
||||
install(new SshJpaModule());
|
||||
install(new WorkspaceJpaModule());
|
||||
install(new MachineJpaModule());
|
||||
install(new FactoryJpaModule());
|
||||
}
|
||||
});
|
||||
|
||||
eventService = injector.getInstance(EventService.class);
|
||||
userDao = injector.getInstance(UserDao.class);
|
||||
preferenceDao = injector.getInstance(PreferenceDao.class);
|
||||
profileDao = injector.getInstance(ProfileDao.class);
|
||||
sshDao = injector.getInstance(SshDao.class);
|
||||
snapshotDao = injector.getInstance(SnapshotDao.class);
|
||||
workspaceDao = injector.getInstance(WorkspaceDao.class);
|
||||
factoryDao = injector.getInstance(FactoryDao.class);
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() {
|
||||
injector.getInstance(EntityManagerFactory.class).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeleteAllTheEntitiesWhenUserIsDeleted() throws Exception {
|
||||
createTestData();
|
||||
|
||||
// Remove the user, all entries must be removed along with the user
|
||||
userDao.remove(user.getId());
|
||||
|
||||
// Check all the entities are removed
|
||||
assertNull(notFoundToNull(() -> userDao.getById(user.getId())));
|
||||
assertNull(notFoundToNull(() -> profileDao.getById(user.getId())));
|
||||
assertTrue(preferenceDao.getPreferences(user.getId()).isEmpty());
|
||||
assertTrue(sshDao.get(user.getId()).isEmpty());
|
||||
assertTrue(workspaceDao.getByNamespace(user.getId()).isEmpty());
|
||||
assertTrue(factoryDao.getByAttribute(0, 0, singletonList(Pair.of("creator.userId", user.getId()))).isEmpty());
|
||||
assertTrue(snapshotDao.findSnapshots(workspace1.getId()).isEmpty());
|
||||
assertTrue(snapshotDao.findSnapshots(workspace2.getId()).isEmpty());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "beforeRemoveRollbackActions")
|
||||
public void shouldRollbackTransactionWhenFailedToRemoveAnyOfEntries(Class<EventSubscriber> eventSubscriber) throws Exception {
|
||||
createTestData();
|
||||
eventService.unsubscribe(injector.getInstance(eventSubscriber));
|
||||
|
||||
// Remove the user, all entries must be rolled back after fail
|
||||
try {
|
||||
userDao.remove(user.getId());
|
||||
fail("UserDao#remove had to throw exception");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// Check all the data rolled back
|
||||
assertNotNull(userDao.getById(user.getId()));
|
||||
assertNotNull(profileDao.getById(user.getId()));
|
||||
assertFalse(preferenceDao.getPreferences(user.getId()).isEmpty());
|
||||
assertFalse(sshDao.get(user.getId()).isEmpty());
|
||||
assertFalse(workspaceDao.getByNamespace(user.getName()).isEmpty());
|
||||
assertFalse(factoryDao.getByAttribute(0, 0, singletonList(Pair.of("creator.userId", user.getId()))).isEmpty());
|
||||
assertFalse(snapshotDao.findSnapshots(workspace1.getId()).isEmpty());
|
||||
assertFalse(snapshotDao.findSnapshots(workspace2.getId()).isEmpty());
|
||||
wipeTestData();
|
||||
}
|
||||
|
||||
@DataProvider(name = "beforeRemoveRollbackActions")
|
||||
public Object[][] beforeRemoveActions() {
|
||||
return new Class[][] {
|
||||
{RemovePreferencesBeforeUserRemovedEventSubscriber.class},
|
||||
{RemoveProfileBeforeUserRemovedEventSubscriber.class},
|
||||
{RemoveWorkspaceBeforeAccountRemovedEventSubscriber.class},
|
||||
{RemoveSnapshotsBeforeWorkspaceRemovedEventSubscriber.class},
|
||||
{RemoveSshKeysBeforeUserRemovedEventSubscriber.class},
|
||||
{RemoveFactoriesBeforeUserRemovedEventSubscriber.class}
|
||||
};
|
||||
}
|
||||
|
||||
private void createTestData() throws ConflictException, ServerException {
|
||||
userDao.create(user = createUser("bobby"));
|
||||
|
||||
profileDao.create(profile = createProfile(user.getId()));
|
||||
|
||||
preferenceDao.setPreferences(user.getId(), preferences = createPreferences());
|
||||
|
||||
workspaceDao.create(workspace1 = createWorkspace("workspace1", user.getAccount()));
|
||||
workspaceDao.create(workspace2 = createWorkspace("workspace2", user.getAccount()));
|
||||
|
||||
sshDao.create(sshPair1 = createSshPair(user.getId(), "service", "name1"));
|
||||
sshDao.create(sshPair2 = createSshPair(user.getId(), "service", "name2"));
|
||||
|
||||
factoryDao.create(factory1 = createFactory("factory1", user.getId()));
|
||||
factoryDao.create(factory2 = createFactory("factory2", user.getId()));
|
||||
|
||||
snapshotDao.saveSnapshot(snapshot1 = createSnapshot("snapshot1", workspace1.getId()));
|
||||
snapshotDao.saveSnapshot(snapshot2 = createSnapshot("snapshot2", workspace1.getId()));
|
||||
snapshotDao.saveSnapshot(snapshot3 = createSnapshot("snapshot3", workspace2.getId()));
|
||||
snapshotDao.saveSnapshot(snapshot4 = createSnapshot("snapshot4", workspace2.getId()));
|
||||
}
|
||||
|
||||
private void wipeTestData() throws ConflictException, ServerException, NotFoundException {
|
||||
snapshotDao.removeSnapshot(snapshot1.getId());
|
||||
snapshotDao.removeSnapshot(snapshot2.getId());
|
||||
snapshotDao.removeSnapshot(snapshot3.getId());
|
||||
snapshotDao.removeSnapshot(snapshot4.getId());
|
||||
|
||||
factoryDao.remove(factory1.getId());
|
||||
factoryDao.remove(factory2.getId());
|
||||
|
||||
sshDao.remove(sshPair1.getOwner(), sshPair1.getService(), sshPair1.getName());
|
||||
sshDao.remove(sshPair2.getOwner(), sshPair2.getService(), sshPair2.getName());
|
||||
|
||||
workspaceDao.remove(workspace1.getId());
|
||||
workspaceDao.remove(workspace2.getId());
|
||||
|
||||
preferenceDao.remove(user.getId());
|
||||
|
||||
profileDao.remove(user.getId());
|
||||
|
||||
userDao.remove(user.getId());
|
||||
}
|
||||
|
||||
private static <T> T notFoundToNull(Callable<T> action) throws Exception {
|
||||
try {
|
||||
return action.call();
|
||||
} catch (NotFoundException x) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.local;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Stage;
|
||||
import com.google.inject.name.Names;
|
||||
import com.google.inject.persist.jpa.JpaPersistModule;
|
||||
|
||||
import org.eclipse.che.api.core.jdbc.jpa.guice.JpaInitializer;
|
||||
import org.eclipse.che.api.local.storage.LocalStorageFactory;
|
||||
import org.eclipse.che.api.local.storage.stack.StackLocalStorage;
|
||||
import org.eclipse.che.api.machine.server.jpa.MachineJpaModule;
|
||||
import org.eclipse.che.api.machine.server.model.impl.SnapshotImpl;
|
||||
import org.eclipse.che.api.machine.server.recipe.RecipeImpl;
|
||||
import org.eclipse.che.api.machine.server.spi.RecipeDao;
|
||||
import org.eclipse.che.api.machine.server.spi.SnapshotDao;
|
||||
import org.eclipse.che.api.ssh.server.jpa.SshJpaModule;
|
||||
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
|
||||
import org.eclipse.che.api.ssh.server.spi.SshDao;
|
||||
import org.eclipse.che.api.user.server.jpa.UserJpaModule;
|
||||
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.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.ProfileDao;
|
||||
import org.eclipse.che.api.user.server.spi.UserDao;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceConfigJsonAdapter;
|
||||
import org.eclipse.che.api.workspace.server.jpa.WorkspaceJpaModule;
|
||||
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.StackDao;
|
||||
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
||||
import org.eclipse.che.api.workspace.server.stack.StackJsonAdapter;
|
||||
import org.eclipse.che.commons.lang.IoUtil;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createPreferences;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createProfile;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createRecipe;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createSnapshot;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createSshPair;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createStack;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createUser;
|
||||
import static org.eclipse.che.api.TestObjectsFactory.createWorkspace;
|
||||
|
||||
/**
|
||||
* Tests migration from local json based storage to jpa.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class LocalToJpaDataMigratorTest {
|
||||
|
||||
private Injector injector;
|
||||
private LocalDataMigrator migrator;
|
||||
private Path workingDir;
|
||||
|
||||
private UserDao userDao;
|
||||
private ProfileDao profileDao;
|
||||
private PreferenceDao preferenceDao;
|
||||
private WorkspaceDao workspaceDao;
|
||||
private SnapshotDao snapshotDao;
|
||||
private SshDao sshDao;
|
||||
private RecipeDao recipeDao;
|
||||
private StackDao stackDao;
|
||||
|
||||
private LocalStorageFactory factory;
|
||||
private StackJsonAdapter stackJsonAdapter;
|
||||
private WorkspaceConfigJsonAdapter workspaceCfgJsonAdapter;
|
||||
|
||||
@BeforeMethod
|
||||
private void setUp() throws Exception {
|
||||
workingDir = Files.createTempDirectory(Paths.get("/tmp"), "test");
|
||||
factory = new LocalStorageFactory(workingDir.toString());
|
||||
injector = Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Names.named("che.conf.storage")).to(workingDir.toString());
|
||||
|
||||
bind(JpaInitializer.class).asEagerSingleton();
|
||||
install(new JpaPersistModule("test"));
|
||||
install(new UserJpaModule());
|
||||
install(new SshJpaModule());
|
||||
install(new WorkspaceJpaModule());
|
||||
install(new MachineJpaModule());
|
||||
bind(StackJsonAdapter.class);
|
||||
}
|
||||
});
|
||||
|
||||
userDao = injector.getInstance(UserDao.class);
|
||||
preferenceDao = injector.getInstance(PreferenceDao.class);
|
||||
profileDao = injector.getInstance(ProfileDao.class);
|
||||
sshDao = injector.getInstance(SshDao.class);
|
||||
snapshotDao = injector.getInstance(SnapshotDao.class);
|
||||
workspaceDao = injector.getInstance(WorkspaceDao.class);
|
||||
recipeDao = injector.getInstance(RecipeDao.class);
|
||||
stackDao = injector.getInstance(StackDao.class);
|
||||
|
||||
stackJsonAdapter = injector.getInstance(StackJsonAdapter.class);
|
||||
workspaceCfgJsonAdapter = injector.getInstance(WorkspaceConfigJsonAdapter.class);
|
||||
|
||||
migrator = new LocalDataMigrator();
|
||||
storeTestData();
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() {
|
||||
IoUtil.deleteRecursive(workingDir.toFile());
|
||||
injector.getInstance(EntityManagerFactory.class).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSuccessfullyPerformMigration() throws Exception {
|
||||
migrator.performMigration(workingDir.toString(),
|
||||
userDao,
|
||||
profileDao,
|
||||
preferenceDao,
|
||||
sshDao,
|
||||
workspaceDao,
|
||||
snapshotDao,
|
||||
recipeDao,
|
||||
stackDao,
|
||||
stackJsonAdapter,
|
||||
workspaceCfgJsonAdapter);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = Exception.class, dataProvider = "failFilenames")
|
||||
public void shouldFailIfEntitiesAreInconsistent(String filename) throws Exception {
|
||||
Files.delete(workingDir.resolve(filename));
|
||||
migrator.performMigration(workingDir.toString(),
|
||||
userDao,
|
||||
profileDao,
|
||||
preferenceDao,
|
||||
sshDao,
|
||||
workspaceDao,
|
||||
snapshotDao,
|
||||
recipeDao,
|
||||
stackDao,
|
||||
stackJsonAdapter,
|
||||
workspaceCfgJsonAdapter);
|
||||
}
|
||||
|
||||
@DataProvider(name = "failFilenames")
|
||||
private Object[][] failFilenames() {
|
||||
return new String[][] {
|
||||
{LocalUserDaoImpl.FILENAME},
|
||||
{LocalWorkspaceDaoImpl.FILENAME}
|
||||
};
|
||||
}
|
||||
|
||||
private void storeTestData() throws Exception {
|
||||
final UserImpl user = createUser("user123");
|
||||
final ProfileImpl profile = createProfile(user.getId());
|
||||
final Map<String, String> preferences = createPreferences();
|
||||
final SshPairImpl pair = createSshPair(user.getId(), "service", "name");
|
||||
final WorkspaceImpl workspace = createWorkspace("id", user.getAccount());
|
||||
final SnapshotImpl snapshot = createSnapshot("snapshot123", workspace.getId());
|
||||
final RecipeImpl recipe = createRecipe("recipe123");
|
||||
final StackImpl stack = createStack("stack123", "stack-name");
|
||||
|
||||
factory.create(LocalUserDaoImpl.FILENAME).store(singletonMap(user.getId(), user));
|
||||
factory.create(LocalProfileDaoImpl.FILENAME).store(singletonMap(profile.getUserId(), profile));
|
||||
factory.create(LocalPreferenceDaoImpl.FILENAME).store(singletonMap(user.getId(), preferences));
|
||||
factory.create(LocalSshDaoImpl.FILENAME, singletonMap(SshPairImpl.class, new SshSerializer()))
|
||||
.store(singletonMap(pair.getOwner(), singletonList(pair)));
|
||||
factory.create(LocalWorkspaceDaoImpl.FILENAME, singletonMap(WorkspaceImpl.class, new WorkspaceSerializer()))
|
||||
.store(singletonMap(workspace.getId(), workspace));
|
||||
factory.create(LocalSnapshotDaoImpl.FILENAME).store(singletonMap(snapshot.getId(), snapshot));
|
||||
factory.create(LocalRecipeDaoImpl.FILENAME).store(singletonMap(recipe.getId(), recipe));
|
||||
factory.create(StackLocalStorage.STACK_STORAGE_FILE).store(singletonMap(stack.getId(), stack));
|
||||
}
|
||||
|
||||
public static class WorkspaceSerializer implements JsonSerializer<WorkspaceImpl> {
|
||||
@Override
|
||||
public JsonElement serialize(WorkspaceImpl src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonElement result = new Gson().toJsonTree(src, WorkspaceImpl.class);
|
||||
result.getAsJsonObject().addProperty("namespace", src.getNamespace());
|
||||
result.getAsJsonObject().remove("account");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SshSerializer implements JsonSerializer<SshPairImpl> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(SshPairImpl sshPair, Type type, JsonSerializationContext jsonSerializationContext) {
|
||||
JsonObject result = new JsonObject();
|
||||
result.add("service", new JsonPrimitive(sshPair.getService()));
|
||||
result.add("name", new JsonPrimitive(sshPair.getName()));
|
||||
result.add("privateKey", new JsonPrimitive(sshPair.getPublicKey()));
|
||||
result.add("publicKey", new JsonPrimitive(sshPair.getPrivateKey()));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0">
|
||||
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
||||
<class>org.eclipse.che.api.user.server.model.impl.UserImpl</class>
|
||||
<class>org.eclipse.che.api.user.server.model.impl.ProfileImpl</class>
|
||||
<class>org.eclipse.che.account.spi.AccountImpl</class>
|
||||
<class>org.eclipse.che.api.user.server.jpa.PreferenceEntity</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.EnvironmentRecipeImpl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.ExtendedMachineImpl</class>
|
||||
<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.ServerConf2Impl</class>
|
||||
<class>org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl</class>
|
||||
<class>org.eclipse.che.api.machine.server.model.impl.CommandImpl</class>
|
||||
<class>org.eclipse.che.api.machine.server.model.impl.MachineSourceImpl</class>
|
||||
<class>org.eclipse.che.api.machine.server.model.impl.SnapshotImpl</class>
|
||||
<class>org.eclipse.che.api.machine.server.recipe.RecipeImpl</class>
|
||||
<class>org.eclipse.che.api.ssh.server.model.impl.SshPairImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.ActionImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.AuthorImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.ButtonAttributesImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.ButtonImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.FactoryImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.IdeImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.OnAppClosedImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.OnProjectsLoadedImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.OnAppLoadedImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.model.impl.PoliciesImpl</class>
|
||||
<class>org.eclipse.che.api.factory.server.FactoryImage</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:"/>
|
||||
<property name="javax.persistence.jdbc.user" value=""/>
|
||||
<property name="javax.persistence.jdbc.password" value=""/>
|
||||
|
||||
<property name="eclipselink.exception-handler" value="org.eclipse.che.api.core.h2.jdbc.jpa.eclipselink.H2ExceptionHandler"/>
|
||||
<property name="eclipselink.target-server" value="None"/>
|
||||
<property name="eclipselink.ddl-generation" value="create-tables"/>
|
||||
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
|
||||
<property name="eclipselink.logging.logger" value="DefaultLogger"/>
|
||||
<property name="eclipselink.logging.level" value="SEVERE"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.acl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public class AclEntryImpl implements AclEntry {
|
||||
private final String user;
|
||||
private final List<String> actions;
|
||||
|
||||
public AclEntryImpl(String user, List<String> actions) {
|
||||
checkArgument(actions != null && !actions.isEmpty(), "Required at least one action");
|
||||
this.user = user;
|
||||
this.actions = new ArrayList<>(actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof AclEntryImpl)) {
|
||||
return false;
|
||||
}
|
||||
final AclEntryImpl other = (AclEntryImpl)obj;
|
||||
return Objects.equals(user, other.user)
|
||||
&& actions.equals(other.actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Objects.hashCode(user);
|
||||
hash = 31 * hash + actions.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AclEntryImpl{" +
|
||||
"user='" + user + "'" +
|
||||
", actions=" + actions +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.security;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static com.google.common.primitives.Ints.tryParse;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Encrypts password using <a href="https://en.wikipedia.org/wiki/PBKDF2">Password-based-Key-Derivative-Function</a>
|
||||
* with <b>SHA512</b> as pseudorandom function.
|
||||
* See <a href="https://www.ietf.org/rfc/rfc2898.txt">rfc2898</a>.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class PBKDF2PasswordEncryptor implements PasswordEncryptor {
|
||||
|
||||
private static final String PWD_FMT = "%s:%s:%d";
|
||||
private static final Pattern PWD_REGEX = Pattern.compile("(?<pwdHash>\\w+):(?<saltHash>\\w+):(?<iterations>[0-9]+)");
|
||||
|
||||
private static final String SECRET_KEY_FACTORY_NAME = "PBKDF2WithHmacSHA512";
|
||||
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
|
||||
/**
|
||||
* Minimum number of iterations required is 1_000(rfc2898),
|
||||
* pick greater as potentially safer in the case of brute-force attacks .
|
||||
*/
|
||||
private static final int ITERATIONS_COUNT = 10_000;
|
||||
/** 64bit salt length based on the rfc2898 spec . */
|
||||
private static final int SALT_LENGTH = 64 / 8;
|
||||
|
||||
@Override
|
||||
public String encrypt(String password) {
|
||||
requireNonNull(password, "Required non-null password");
|
||||
final byte[] salt = new byte[SALT_LENGTH];
|
||||
SECURE_RANDOM.nextBytes(salt);
|
||||
final HashCode hash = computeHash(password.toCharArray(), salt, ITERATIONS_COUNT);
|
||||
final HashCode saltHash = HashCode.fromBytes(salt);
|
||||
return format(PWD_FMT, hash, saltHash, ITERATIONS_COUNT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(String password, String encryptedPassword) {
|
||||
requireNonNull(password, "Required non-null password");
|
||||
requireNonNull(password, "Required non-null encrypted password");
|
||||
final Matcher matcher = PWD_REGEX.matcher(encryptedPassword);
|
||||
if (!matcher.matches()) {
|
||||
return false;
|
||||
}
|
||||
// retrieve salt, password hash and iterations count from hash
|
||||
final Integer iterations = tryParse(matcher.group("iterations"));
|
||||
final String salt = matcher.group("saltHash");
|
||||
final String pwdHash = matcher.group("pwdHash");
|
||||
// compute password's hash and test whether it matches to given hash
|
||||
final HashCode hash = computeHash(password.toCharArray(), HashCode.fromString(salt).asBytes(), iterations);
|
||||
return hash.toString().equals(pwdHash);
|
||||
}
|
||||
|
||||
private HashCode computeHash(char[] password, byte[] salt, int iterations) {
|
||||
try {
|
||||
final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_NAME);
|
||||
final KeySpec keySpec = new PBEKeySpec(password, salt, iterations, 512);
|
||||
return HashCode.fromBytes(keyFactory.generateSecret(keySpec).getEncoded());
|
||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException x) {
|
||||
throw new RuntimeException(x.getMessage(), x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.security;
|
||||
|
||||
/**
|
||||
* Encrypts password in implementation specific way.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface PasswordEncryptor {
|
||||
|
||||
/**
|
||||
* Encrypts the given {@code password}.
|
||||
*
|
||||
* @param password
|
||||
* the plain password to be encrypted
|
||||
* @return the encrypted password
|
||||
* @throws NullPointerException
|
||||
* when the password is null
|
||||
* @throws RuntimeException
|
||||
* when any error occurs during password encryption
|
||||
*/
|
||||
String encrypt(String password);
|
||||
|
||||
/**
|
||||
* Tests whether given {@code password} is {@code encryptedPassword}.
|
||||
*
|
||||
* @param encryptedPassword
|
||||
* encrypted password
|
||||
* @param password
|
||||
* the password to check
|
||||
* @return true if given {@code password} is {@code encryptedPassword}
|
||||
* @throws NullPointerException
|
||||
* when either of arguments is null
|
||||
* @throws RuntimeException
|
||||
* when any error occurs during test
|
||||
*/
|
||||
boolean test(String password, String encryptedPassword);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.security;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.primitives.Bytes;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* SHA-512 based encryptor {@code hash = sha512(password + salt) + salt}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class SHA512PasswordEncryptor implements PasswordEncryptor {
|
||||
|
||||
/** 64 bit salt length is based on the <a href="https://www.ietf.org/rfc/rfc2898.txt">source</a>. */
|
||||
private static final int SALT_BYTES_LENGTH = 64 / 8;
|
||||
/** SHA-512 produces 512 bits. */
|
||||
private static final int ENCRYPTED_PASSWORD_BYTES_LENGTH = 512 / 8;
|
||||
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
|
||||
private static final Charset PWD_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
@Override
|
||||
public String encrypt(String password) {
|
||||
requireNonNull(password, "Required non-null password");
|
||||
// generate salt
|
||||
final byte[] salt = new byte[SALT_BYTES_LENGTH];
|
||||
SECURE_RANDOM.nextBytes(salt);
|
||||
// sha512(password + salt)
|
||||
final HashCode hash = Hashing.sha512().hashBytes(Bytes.concat(password.getBytes(PWD_CHARSET), salt));
|
||||
final HashCode saltHash = HashCode.fromBytes(salt);
|
||||
// add salt to the hash, result length (512 / 8) * 2 + (64 / 8) * 2 = 144
|
||||
return hash.toString() + saltHash.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(String password, String passwordHash) {
|
||||
requireNonNull(password, "Required non-null password");
|
||||
requireNonNull(passwordHash, "Required non-null password's hash");
|
||||
// retrieve salt from the hash
|
||||
final int passwordHashLength = ENCRYPTED_PASSWORD_BYTES_LENGTH * 2;
|
||||
if (passwordHash.length() < passwordHashLength + SALT_BYTES_LENGTH * 2) {
|
||||
return false;
|
||||
}
|
||||
final HashCode saltHash = HashCode.fromString(passwordHash.substring(passwordHashLength));
|
||||
// sha1(password + salt)
|
||||
final HashCode hash = Hashing.sha512().hashBytes(Bytes.concat(password.getBytes(PWD_CHARSET), saltHash.asBytes()));
|
||||
// test sha1(password + salt) + salt == passwordHash
|
||||
return (hash.toString() + saltHash.toString()).equals(passwordHash);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.security;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class PasswordEncryptorsTest {
|
||||
|
||||
@Test(dataProvider = "encryptorsProvider")
|
||||
public void testEncryption(PasswordEncryptor encryptor) throws Exception {
|
||||
final String password = "password";
|
||||
|
||||
final String hash = encryptor.encrypt(password);
|
||||
assertNotNull(hash, "encrypted password's hash");
|
||||
|
||||
assertTrue(encryptor.test(password, hash), "password test");
|
||||
}
|
||||
|
||||
@DataProvider(name = "encryptorsProvider")
|
||||
public Object[][] encryptorsProvider() {
|
||||
return new Object[][] {
|
||||
{new SHA512PasswordEncryptor()},
|
||||
{new PBKDF2PasswordEncryptor()}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>5.0.0-M2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-jdbc-vendor-h2</artifactId>
|
||||
<name>Che Core :: API :: JDBC Vendor H2</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>eclipselink</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.h2.jdbc.jpa.eclipselink;
|
||||
|
||||
import org.eclipse.che.api.core.jdbc.jpa.DuplicateKeyException;
|
||||
import org.eclipse.che.api.core.jdbc.jpa.IntegrityConstraintViolationException;
|
||||
import org.eclipse.persistence.exceptions.DatabaseException;
|
||||
import org.eclipse.persistence.exceptions.ExceptionHandler;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Rethrows vendor specific exceptions as common exceptions.
|
||||
* See <a href="http://www.h2database.com/javadoc/org/h2/api/ErrorCode.html">H2 error codes</a>.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class H2ExceptionHandler implements ExceptionHandler {
|
||||
|
||||
public Object handleException(RuntimeException exception) {
|
||||
if (exception instanceof DatabaseException && exception.getCause() instanceof SQLException) {
|
||||
final SQLException sqlEx = (SQLException)exception.getCause();
|
||||
switch (sqlEx.getErrorCode()) {
|
||||
case 23505:
|
||||
throw new DuplicateKeyException(exception.getMessage(), exception);
|
||||
case 23506:
|
||||
throw new IntegrityConstraintViolationException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>5.0.0-M2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-jdbc</artifactId>
|
||||
<name>Che Core :: API :: JDBC</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>eclipselink</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.jdbc;
|
||||
|
||||
/**
|
||||
* Defines common database error codes which should
|
||||
* be used throughout the application in preference to
|
||||
* vendor specific error codes.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public enum DBErrorCode {
|
||||
|
||||
/**
|
||||
* When database error can't be described with one
|
||||
* of the other values of this enumeration.
|
||||
*/
|
||||
UNDEFINED(-1),
|
||||
|
||||
/**
|
||||
* When any of the unique constraints is violated
|
||||
* e.g. duplicate key or unique index violation.
|
||||
*/
|
||||
DUPLICATE_KEY(1),
|
||||
|
||||
/**
|
||||
* When entity referenced foreign key does not exist
|
||||
*/
|
||||
INTEGRITY_CONSTRAINT_VIOLATION(2);
|
||||
|
||||
private final int code;
|
||||
|
||||
DBErrorCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code of this error.
|
||||
*/
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.jdbc.jpa;
|
||||
|
||||
import org.eclipse.che.api.core.jdbc.DBErrorCode;
|
||||
|
||||
import javax.persistence.RollbackException;
|
||||
|
||||
/**
|
||||
* Extends the standard {@link RollbackException} with an error code from {@link DBErrorCode}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class DetailedRollbackException extends RollbackException {
|
||||
|
||||
private DBErrorCode code;
|
||||
|
||||
public DetailedRollbackException(String message, Throwable cause, DBErrorCode code) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public DBErrorCode getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.jdbc.jpa;
|
||||
|
||||
import org.eclipse.che.api.core.jdbc.DBErrorCode;
|
||||
|
||||
/**
|
||||
* Thrown when data couldn't be updated/stored due to unique constrain violation.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @see DBErrorCode#DUPLICATE_KEY
|
||||
*/
|
||||
public class DuplicateKeyException extends DetailedRollbackException {
|
||||
|
||||
public DuplicateKeyException(String message, Throwable cause) {
|
||||
super(message, cause, DBErrorCode.DUPLICATE_KEY);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.jdbc.jpa;
|
||||
|
||||
import org.eclipse.che.api.core.jdbc.DBErrorCode;
|
||||
|
||||
import static org.eclipse.che.api.core.jdbc.DBErrorCode.INTEGRITY_CONSTRAINT_VIOLATION;
|
||||
|
||||
/**
|
||||
* Throws during inserts/updates entity that restricted by referential integrity
|
||||
* and given insert/update refers to non-existing entity.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
* @see DBErrorCode#INTEGRITY_CONSTRAINT_VIOLATION
|
||||
*/
|
||||
public class IntegrityConstraintViolationException extends DetailedRollbackException {
|
||||
|
||||
public IntegrityConstraintViolationException(String message, Throwable cause) {
|
||||
super(message, cause, INTEGRITY_CONSTRAINT_VIOLATION);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.jdbc.jpa.eclipselink;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.eclipse.persistence.sessions.server.ServerSession;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
/**
|
||||
* Sets up {@link GuiceEntityListenerInjectionManager}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class EntityListenerInjectionManagerInitializer {
|
||||
|
||||
@Inject
|
||||
public EntityListenerInjectionManagerInitializer(GuiceEntityListenerInjectionManager injManager, EntityManagerFactory emFactory) {
|
||||
final ServerSession session = emFactory.unwrap(ServerSession.class);
|
||||
session.setEntityListenerInjectionManager(injManager);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.jdbc.jpa.eclipselink;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||
import org.eclipse.persistence.internal.sessions.cdi.EntityListenerInjectionManager;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* Allows to use dependency injection in entity listeners.
|
||||
*
|
||||
* <p>Example:
|
||||
* <pre>
|
||||
* class WorkspaceEntityListener {
|
||||
*
|
||||
* @Inject EventBus bus; <- EventBus will be injected by Guice
|
||||
*
|
||||
* @PreRemove
|
||||
* public void preRemove(Workspace workspace) {
|
||||
* bus.post(new BeforeWorkspaceRemovedEvent(workspace));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Entity
|
||||
* @EntityListeners(WorkspaceEntityListener.class)
|
||||
* class Workspace {
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class GuiceEntityListenerInjectionManager implements EntityListenerInjectionManager {
|
||||
|
||||
@Inject
|
||||
private Injector injector;
|
||||
|
||||
@Override
|
||||
public Object createEntityListenerAndInjectDependancies(Class entityListenerClass) throws NamingException {
|
||||
try {
|
||||
return injector.getInstance(entityListenerClass);
|
||||
} catch (RuntimeException x) {
|
||||
throw new NamingException(x.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp(AbstractSession session) {
|
||||
// EntityListener objects are managed by Guice, nothing to cleanup
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.jdbc.jpa.guice;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.PersistService;
|
||||
|
||||
/**
|
||||
* Should be bound as eager singleton.
|
||||
* See <a href="https://github.com/google/guice/wiki/JPA">doc</a>
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class JpaInitializer {
|
||||
|
||||
@Inject
|
||||
public JpaInitializer(PersistService persistService) {
|
||||
persistService.start();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Defines the contract for the factory action instance.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface Action {
|
||||
|
||||
/**
|
||||
* Returns the IDE specific identifier of action e.g. ('openFile', 'editFile')
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns properties of this action instance
|
||||
*/
|
||||
Map<String, String> getProperties();
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
/**
|
||||
* Defines the contract for the factory creator instance.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface Author {
|
||||
|
||||
/**
|
||||
* Identifier of the user who created factory, it is mandatory
|
||||
*/
|
||||
String getUserId();
|
||||
|
||||
/**
|
||||
* Creation time of factory, set by the server (in milliseconds, from Unix epoch, no timezone)
|
||||
*/
|
||||
Long getCreated();
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
/**
|
||||
* Defines factory button.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface Button {
|
||||
|
||||
enum Type {
|
||||
LOGO {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "logo";
|
||||
}
|
||||
},
|
||||
NOLOGO {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "nologo";
|
||||
}
|
||||
};
|
||||
|
||||
public static Type getIgnoreCase(String name) {
|
||||
for (Type type : values()) {
|
||||
if (name.equalsIgnoreCase(type.toString())) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns type of this button instance
|
||||
*/
|
||||
Type getType();
|
||||
|
||||
/**
|
||||
* Returns attributes of this button instance
|
||||
*/
|
||||
ButtonAttributes getAttributes();
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
/**
|
||||
* Defines factory button attributes.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface ButtonAttributes {
|
||||
|
||||
/**
|
||||
* Returns factory button color
|
||||
*/
|
||||
String getColor();
|
||||
|
||||
/**
|
||||
* Returns factory button counter
|
||||
*/
|
||||
Boolean getCounter();
|
||||
|
||||
/**
|
||||
* Returns factory button logo
|
||||
*/
|
||||
String getLogo();
|
||||
|
||||
/**
|
||||
* Returns factory button style
|
||||
*/
|
||||
String getStyle();
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
|
||||
|
||||
/**
|
||||
* Defines the contract for the factory instance.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface Factory {
|
||||
|
||||
/**
|
||||
* Returns the identifier of this factory instance,
|
||||
* it is mandatory and unique.
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the version of this factory instance,
|
||||
* it is mandatory.
|
||||
*/
|
||||
String getV();
|
||||
|
||||
/**
|
||||
* Returns a name of this factory instance,
|
||||
* the name is unique for creator.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns creator of this factory instance.
|
||||
*/
|
||||
Author getCreator();
|
||||
|
||||
/**
|
||||
* Returns a workspace configuration of this factory instance,
|
||||
* it is mandatory for every factory instance.
|
||||
*/
|
||||
WorkspaceConfig getWorkspace();
|
||||
|
||||
/**
|
||||
* Returns restrictions of this factory instance.
|
||||
*/
|
||||
Policies getPolicies();
|
||||
|
||||
/**
|
||||
* Returns factory button for this instance.
|
||||
*/
|
||||
Button getButton();
|
||||
|
||||
/**
|
||||
* Returns IDE for this factory instance.
|
||||
*/
|
||||
Ide getIde();
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
/**
|
||||
* Defines the contract for the factory IDE instance.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface Ide {
|
||||
|
||||
/**
|
||||
* Returns configuration of IDE on application loaded event
|
||||
*/
|
||||
OnAppLoaded getOnAppLoaded();
|
||||
|
||||
/**
|
||||
* Returns configuration of IDE on application closed event
|
||||
*/
|
||||
OnAppClosed getOnAppClosed();
|
||||
|
||||
/**
|
||||
* Returns configuration of IDE on projects loaded event
|
||||
*/
|
||||
OnProjectsLoaded getOnProjectsLoaded();
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Defines IDE look and feel on application closed event.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface OnAppClosed {
|
||||
|
||||
/**
|
||||
* Returns actions for current event.
|
||||
*/
|
||||
List<? extends Action> getActions();
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Defines IDE look and feel on application loaded event.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface OnAppLoaded {
|
||||
|
||||
/**
|
||||
* Returns actions for current event.
|
||||
*/
|
||||
List<? extends Action> getActions();
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Defines IDE look and feel on project opened event.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface OnProjectsLoaded {
|
||||
|
||||
/**
|
||||
* Returns actions for current event.
|
||||
*/
|
||||
List<? extends Action> getActions();
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.factory;
|
||||
|
||||
/**
|
||||
* Defines the contract for the factory restrictions.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface Policies {
|
||||
|
||||
/**
|
||||
* Restrict access if referer header doesn't match this field
|
||||
*/
|
||||
String getReferer();
|
||||
|
||||
/**
|
||||
* Restrict access for factories used earlier then author supposes
|
||||
*/
|
||||
Long getSince();
|
||||
|
||||
/**
|
||||
* Restrict access for factories used later then author supposes
|
||||
*/
|
||||
Long getUntil();
|
||||
|
||||
/**
|
||||
* Re-open projects on factory 2-nd click
|
||||
*/
|
||||
String getMatch();
|
||||
|
||||
/**
|
||||
* Workspace creation strategy
|
||||
*/
|
||||
String getCreate();
|
||||
}
|
||||
|
|
@ -28,12 +28,6 @@ public interface Snapshot {
|
|||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* Snapshot namespace, which allows snapshot to be
|
||||
* related to the certain workspace machine.
|
||||
*/
|
||||
String getNamespace();
|
||||
|
||||
/**
|
||||
* Creation date of the snapshot
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ public interface Workspace {
|
|||
*/
|
||||
String getNamespace();
|
||||
|
||||
/**
|
||||
* Returns the name of the current workspace instance.
|
||||
* Workspace name is unique per namespace.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the status of the current workspace instance.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -26,7 +26,11 @@ import java.util.Map;
|
|||
public interface WorkspaceConfig {
|
||||
|
||||
/**
|
||||
* Returns workspace name.
|
||||
* Optional.
|
||||
* Returns possible name of the workspace created from this configuration.
|
||||
* If name doesn't conflict then the target workspace
|
||||
* will have exactly the same name, but if the name conflicts or it is absent
|
||||
* then any other name will be chose for the workspace.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
|
|
|
|||
|
|
@ -43,10 +43,20 @@
|
|||
<artifactId>guice</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck;
|
||||
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestListener;
|
||||
import org.testng.ITestResult;
|
||||
|
||||
/**
|
||||
* Skeletal implementation of the {@link ITestListener}.
|
||||
* In most cases only 2 methods are needed {@link #onStart(ITestContext)} and {@link #onFinish(ITestContext)}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public abstract class AbstractTestListener implements ITestListener {
|
||||
|
||||
@Override
|
||||
public void onTestStart(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestSuccess(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestFailure(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestSkipped(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onStart(ITestContext context) {}
|
||||
|
||||
@Override
|
||||
public void onFinish(ITestContext context) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck.repository;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.UnitOfWork;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.Collection;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Simplifies implementation for Jpa repository in general case.
|
||||
*
|
||||
* Expected usage:
|
||||
* <pre>
|
||||
* class MyTckModule extends TckModule {
|
||||
* @Override configure() {
|
||||
* bind(new TypeLiteral<TckRepository<UserImpl>>() {})
|
||||
* .toInstance(new JpaTckRepository(Concrete.class));
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param <T>
|
||||
* type of the entity
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class JpaTckRepository<T> implements TckRepository<T> {
|
||||
|
||||
@Inject
|
||||
protected Provider<EntityManager> managerProvider;
|
||||
|
||||
@Inject
|
||||
protected UnitOfWork uow;
|
||||
|
||||
private final Class<T> entityClass;
|
||||
|
||||
public JpaTckRepository(Class<T> entityClass) {
|
||||
this.entityClass = entityClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAll(Collection<? extends T> entities) throws TckRepositoryException {
|
||||
uow.begin();
|
||||
final EntityManager manager = managerProvider.get();
|
||||
try {
|
||||
manager.getTransaction().begin();
|
||||
entities.forEach(manager::persist);
|
||||
manager.getTransaction().commit();
|
||||
} catch (RuntimeException x) {
|
||||
if (manager.getTransaction().isActive()) {
|
||||
manager.getTransaction().rollback();
|
||||
}
|
||||
throw new TckRepositoryException(x.getLocalizedMessage(), x);
|
||||
} finally {
|
||||
uow.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAll() throws TckRepositoryException {
|
||||
uow.begin();
|
||||
final EntityManager manager = managerProvider.get();
|
||||
try {
|
||||
manager.getTransaction().begin();
|
||||
// The query 'DELETE FROM Entity' won't be correct as it will ignore orphanRemoval
|
||||
// and may also ignore some configuration options, while EntityManager#remove won't
|
||||
manager.createQuery(format("SELECT e FROM %s e", getEntityName(entityClass)), entityClass)
|
||||
.getResultList()
|
||||
.forEach(manager::remove);
|
||||
manager.getTransaction().commit();
|
||||
} catch (RuntimeException x) {
|
||||
if (manager.getTransaction().isActive()) {
|
||||
manager.getTransaction().rollback();
|
||||
}
|
||||
throw new TckRepositoryException(x.getLocalizedMessage(), x);
|
||||
} finally {
|
||||
uow.end();
|
||||
}
|
||||
}
|
||||
|
||||
private String getEntityName(Class<?> clazz) {
|
||||
if (!clazz.isAnnotationPresent(Entity.class)) {
|
||||
return clazz.getSimpleName();
|
||||
}
|
||||
final Entity entity = clazz.getAnnotation(Entity.class);
|
||||
if (entity.name().isEmpty()) {
|
||||
return clazz.getSimpleName();
|
||||
}
|
||||
return entity.name();
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import org.testng.ITestResult;
|
|||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class DBServerListener implements ITestListener {
|
||||
public class DBServerListener extends AbstractTestListener {
|
||||
|
||||
public static final String DB_SERVER_URL_ATTRIBUTE_NAME = "db_server_url";
|
||||
public static final String DB_SERVER_URL = "localhost:12345";
|
||||
|
|
@ -29,22 +29,4 @@ public class DBServerListener implements ITestListener {
|
|||
public void onStart(ITestContext context) {
|
||||
context.setAttribute(DB_SERVER_URL_ATTRIBUTE_NAME, DB_SERVER_URL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(ITestContext context) {}
|
||||
|
||||
@Override
|
||||
public void onTestStart(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestSuccess(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestFailure(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestSkipped(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,5 +30,7 @@
|
|||
<module>che-core-api-dto-maven-plugin</module>
|
||||
<module>che-core-api-core</module>
|
||||
<module>che-core-api-model</module>
|
||||
<module>che-core-api-jdbc</module>
|
||||
<module>che-core-api-jdbc-vendor-h2</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ package org.eclipse.che.ide.api.app;
|
|||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.ide.api.machine.DevMachine;
|
||||
import org.eclipse.che.ide.api.resources.Container;
|
||||
|
|
@ -175,12 +176,15 @@ public interface AppContext {
|
|||
void setStartUpActions(List<StartUpAction> startUpActions);
|
||||
|
||||
/**
|
||||
* Returns {@link Factory} instance which id was set on startup, or {@code null} if no factory was specified.
|
||||
* Returns {@link Factory} instance which id was set on startup,
|
||||
* or {@code null} if no factory was specified.
|
||||
*
|
||||
* @return loaded factory or {@code null}
|
||||
*/
|
||||
Factory getFactory();
|
||||
FactoryDto getFactory();
|
||||
|
||||
void setFactory(FactoryDto factory);
|
||||
|
||||
String getWorkspaceId();
|
||||
|
||||
/* Deprecated methods */
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ package org.eclipse.che.ide.api.factory;
|
|||
|
||||
import com.google.gwt.event.shared.GwtEvent;
|
||||
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -22,9 +22,9 @@ import org.eclipse.che.api.factory.shared.dto.Factory;
|
|||
*/
|
||||
public class FactoryAcceptedEvent extends GwtEvent<FactoryAcceptedHandler> {
|
||||
|
||||
private Factory factory;
|
||||
private FactoryDto factory;
|
||||
|
||||
public FactoryAcceptedEvent(Factory factory) {
|
||||
public FactoryAcceptedEvent(FactoryDto factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ public class FactoryAcceptedEvent extends GwtEvent<FactoryAcceptedHandler> {
|
|||
|
||||
}
|
||||
|
||||
public Factory getFactory() {
|
||||
public FactoryDto getFactory() {
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.factory;
|
||||
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
|
|
@ -36,7 +36,7 @@ public interface FactoryServiceClient {
|
|||
* indicates whether or not factory should be validated by accept validator
|
||||
* @return Factory through a Promise
|
||||
*/
|
||||
Promise<Factory> getFactory(@NotNull String factoryId, boolean validate);
|
||||
Promise<FactoryDto> getFactory(@NotNull String factoryId, boolean validate);
|
||||
|
||||
/**
|
||||
* @param factoryId
|
||||
|
|
@ -58,7 +58,7 @@ public interface FactoryServiceClient {
|
|||
* @param callback
|
||||
* callback which returns snippet of the factory or exception if occurred
|
||||
*/
|
||||
void getFactoryJson(@NotNull String workspaceId, @NotNull String path, @NotNull AsyncRequestCallback<Factory> callback);
|
||||
void getFactoryJson(@NotNull String workspaceId, @NotNull String path, @NotNull AsyncRequestCallback<FactoryDto> callback);
|
||||
|
||||
/**
|
||||
* Get factory as JSON.
|
||||
|
|
@ -67,18 +67,18 @@ public interface FactoryServiceClient {
|
|||
* workspace id
|
||||
* @param path
|
||||
* project path
|
||||
* @return a promise that resolves to the {@link Factory}, or rejects with an error
|
||||
* @return a promise that resolves to the {@link FactoryDto}, or rejects with an error
|
||||
*/
|
||||
Promise<Factory> getFactoryJson(@NotNull String workspaceId, @Nullable String path);
|
||||
Promise<FactoryDto> getFactoryJson(@NotNull String workspaceId, @Nullable String path);
|
||||
|
||||
/**
|
||||
* Save factory to storage.
|
||||
*
|
||||
* @param factory
|
||||
* factory to save
|
||||
* @return a promise that resolves to the {@link Factory}, or rejects with an error
|
||||
* @return a promise that resolves to the {@link FactoryDto}, or rejects with an error
|
||||
*/
|
||||
Promise<Factory> saveFactory(@NotNull Factory factory);
|
||||
Promise<FactoryDto> saveFactory(@NotNull FactoryDto factory);
|
||||
|
||||
/**
|
||||
* Save factory to storage.
|
||||
|
|
@ -87,9 +87,9 @@ public interface FactoryServiceClient {
|
|||
* the number of the items to skip
|
||||
* @param maxItems
|
||||
* the limit of the items in the response, default is 30
|
||||
* @return a promise that will provide a list of {@link Factory}s, or rejects with an error
|
||||
* @return a promise that will provide a list of {@link FactoryDto}s, or rejects with an error
|
||||
*/
|
||||
Promise<List<Factory>> findFactory(Integer skipCount, Integer maxItems, List<Pair<String, String>> params);
|
||||
Promise<List<FactoryDto>> findFactory(Integer skipCount, Integer maxItems, List<Pair<String, String>> params);
|
||||
|
||||
/**
|
||||
* Updates factory by id
|
||||
|
|
@ -100,7 +100,7 @@ public interface FactoryServiceClient {
|
|||
* update body
|
||||
* @return updated factory
|
||||
*/
|
||||
Promise<Factory> updateFactory(String id, Factory factory);
|
||||
Promise<FactoryDto> updateFactory(String id, FactoryDto factory);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -112,6 +112,6 @@ public interface FactoryServiceClient {
|
|||
* indicates whether or not factory should be validated by accept validator
|
||||
* @return Factory through a Promise
|
||||
*/
|
||||
Promise<Factory> resolveFactory(@NotNull Map<String, String> factoryParameters, boolean validate);
|
||||
Promise<FactoryDto> resolveFactory(@NotNull Map<String, String> factoryParameters, boolean validate);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.google.gwt.http.client.RequestBuilder;
|
|||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.ide.MimeType;
|
||||
|
|
@ -68,13 +68,13 @@ public class FactoryServiceClientImpl implements FactoryServiceClient {
|
|||
* @return Factory through a Promise
|
||||
*/
|
||||
@Override
|
||||
public Promise<Factory> getFactory(@NotNull String factoryId, boolean validate) {
|
||||
public Promise<FactoryDto> getFactory(@NotNull String factoryId, boolean validate) {
|
||||
StringBuilder url = new StringBuilder(API_FACTORY_BASE_URL).append(factoryId);
|
||||
if (validate) {
|
||||
url.append("?").append("validate=true");
|
||||
}
|
||||
return asyncRequestFactory.createGetRequest(url.toString()).header(HTTPHeader.ACCEPT, MimeType.APPLICATION_JSON)
|
||||
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
|
||||
.send(unmarshallerFactory.newUnmarshaller(FactoryDto.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -90,7 +90,7 @@ public class FactoryServiceClientImpl implements FactoryServiceClient {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void getFactoryJson(String workspaceId, String path, AsyncRequestCallback<Factory> callback) {
|
||||
public void getFactoryJson(String workspaceId, String path, AsyncRequestCallback<FactoryDto> callback) {
|
||||
final StringBuilder url = new StringBuilder(API_FACTORY_BASE_URL + "workspace/").append(workspaceId);
|
||||
if (path != null) {
|
||||
url.append("?path=").append(path);
|
||||
|
|
@ -102,7 +102,7 @@ public class FactoryServiceClientImpl implements FactoryServiceClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Promise<Factory> getFactoryJson(String workspaceId, String path) {
|
||||
public Promise<FactoryDto> getFactoryJson(String workspaceId, String path) {
|
||||
String url = API_FACTORY_BASE_URL + "workspace/" + workspaceId;
|
||||
if (path != null) {
|
||||
url += path;
|
||||
|
|
@ -111,20 +111,20 @@ public class FactoryServiceClientImpl implements FactoryServiceClient {
|
|||
return asyncRequestFactory.createGetRequest(url)
|
||||
.header(HTTPHeader.ACCEPT, MimeType.APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Getting info about factory..."))
|
||||
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
|
||||
.send(unmarshallerFactory.newUnmarshaller(FactoryDto.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Factory> saveFactory(@NotNull Factory factory) {
|
||||
public Promise<FactoryDto> saveFactory(@NotNull FactoryDto factory) {
|
||||
return asyncRequestFactory.createPostRequest(API_FACTORY_BASE_URL, factory)
|
||||
.header(HTTPHeader.ACCEPT, MimeType.APPLICATION_JSON)
|
||||
.header(HTTPHeader.CONTENT_TYPE, MimeType.APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Creating factory..."))
|
||||
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
|
||||
.send(unmarshallerFactory.newUnmarshaller(FactoryDto.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<List<Factory>> findFactory(@Nullable Integer skipCount,
|
||||
public Promise<List<FactoryDto>> findFactory(@Nullable Integer skipCount,
|
||||
@Nullable Integer maxItems,
|
||||
@Nullable List<Pair<String, String>> params) {
|
||||
final List<Pair<String, String>> allParams = new LinkedList<>();
|
||||
|
|
@ -141,15 +141,15 @@ public class FactoryServiceClientImpl implements FactoryServiceClient {
|
|||
.header(HTTPHeader.ACCEPT, MimeType.APPLICATION_JSON)
|
||||
.header(HTTPHeader.CONTENT_TYPE, MimeType.APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Searching factory..."))
|
||||
.send(unmarshallerFactory.newListUnmarshaller(Factory.class));
|
||||
.send(unmarshallerFactory.newListUnmarshaller(FactoryDto.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Factory> updateFactory(String id, Factory factory) {
|
||||
public Promise<FactoryDto> updateFactory(String id, FactoryDto factory) {
|
||||
return asyncRequestFactory.createRequest(RequestBuilder.PUT, API_FACTORY_BASE_URL + id, factory, false)
|
||||
.header(HTTPHeader.CONTENT_TYPE, MimeType.APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Updating factory..."))
|
||||
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
|
||||
.send(unmarshallerFactory.newUnmarshaller(FactoryDto.class));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ public class FactoryServiceClientImpl implements FactoryServiceClient {
|
|||
* @return Factory through a Promise
|
||||
*/
|
||||
@Override
|
||||
public Promise<Factory> resolveFactory(@NotNull final Map<String, String> factoryParameters, boolean validate) {
|
||||
public Promise<FactoryDto> resolveFactory(@NotNull final Map<String, String> factoryParameters, boolean validate) {
|
||||
|
||||
// Init string with JAX-RS path
|
||||
StringBuilder url = new StringBuilder(API_FACTORY_BASE_URL + "resolver");
|
||||
|
|
@ -173,7 +173,7 @@ public class FactoryServiceClientImpl implements FactoryServiceClient {
|
|||
url.append("?validate=true");
|
||||
}
|
||||
return asyncRequestFactory.createPostRequest(url.toString(), toJson(factoryParameters)).header(ACCEPT, APPLICATION_JSON)
|
||||
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
|
||||
.send(unmarshallerFactory.newUnmarshaller(FactoryDto.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
<source path="machine"/>
|
||||
<source path="project"/>
|
||||
<source path="workspace"/>
|
||||
<source path="factory"/>
|
||||
<source path="user"/>
|
||||
|
||||
</module>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import com.google.inject.Provider;
|
|||
import com.google.inject.Singleton;
|
||||
import com.google.web.bindery.event.shared.EventBus;
|
||||
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.api.promises.client.OperationException;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
|
|
@ -82,11 +82,11 @@ public class AppContextImpl implements AppContext,
|
|||
private final BrowserQueryFieldRenderer browserQueryFieldRenderer;
|
||||
private final List<String> projectsInImport;
|
||||
|
||||
private WorkspaceDto usersWorkspaceDto;
|
||||
private CurrentUser currentUser;
|
||||
private Factory factory;
|
||||
private DevMachine devMachine;
|
||||
private Path projectsRoot;
|
||||
private WorkspaceDto usersWorkspaceDto;
|
||||
private CurrentUser currentUser;
|
||||
private FactoryDto factory;
|
||||
private DevMachine devMachine;
|
||||
private Path projectsRoot;
|
||||
/**
|
||||
* List of actions with parameters which comes from startup URL.
|
||||
* Can be processed after IDE initialization as usual after starting ws-agent.
|
||||
|
|
@ -170,11 +170,12 @@ public class AppContextImpl implements AppContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public Factory getFactory() {
|
||||
public FactoryDto getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
public void setFactory(Factory factory) {
|
||||
@Override
|
||||
public void setFactory(FactoryDto factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import com.google.inject.Singleton;
|
|||
import com.google.web.bindery.event.shared.EventBus;
|
||||
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.promises.client.Function;
|
||||
import org.eclipse.che.api.promises.client.FunctionException;
|
||||
import org.eclipse.che.api.promises.client.Operation;
|
||||
|
|
@ -119,7 +119,7 @@ public class FactoryWorkspaceComponent extends WorkspaceComponent {
|
|||
// get workspace ID to use dedicated workspace for this factory
|
||||
this.workspaceId = browserQueryFieldRenderer.getParameterFromURLByName("workspaceId");
|
||||
|
||||
Promise<Factory> factoryPromise;
|
||||
Promise<FactoryDto> factoryPromise;
|
||||
// now search if it's a factory based on id or from parameters
|
||||
if (factoryParameters.containsKey("id")) {
|
||||
factoryPromise = factoryServiceClient.getFactory(factoryParameters.get("id"), true);
|
||||
|
|
@ -127,9 +127,10 @@ public class FactoryWorkspaceComponent extends WorkspaceComponent {
|
|||
factoryPromise = factoryServiceClient.resolveFactory(factoryParameters, true);
|
||||
}
|
||||
|
||||
factoryPromise.then(new Function<Factory, Void>() {
|
||||
Promise<Void> promise = factoryPromise.then(new Function<FactoryDto, Void>() {
|
||||
@Override
|
||||
public Void apply(final Factory factory) throws FunctionException {
|
||||
public Void apply(final FactoryDto factory) throws FunctionException {
|
||||
|
||||
if (appContext instanceof AppContextImpl) {
|
||||
((AppContextImpl)appContext).setFactory(factory);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import java.util.Map;
|
|||
public class WorkspaceImpl implements Workspace {
|
||||
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final WorkspaceRuntime workspaceRuntime;
|
||||
private final String namespace;
|
||||
private final WorkspaceStatus status;
|
||||
|
|
@ -32,8 +33,10 @@ public class WorkspaceImpl implements Workspace {
|
|||
private final boolean temporary;
|
||||
private final WorkspaceConfig config;
|
||||
|
||||
|
||||
public WorkspaceImpl(Workspace workspace) {
|
||||
id = workspace.getId();
|
||||
name = workspace.getName();
|
||||
workspaceRuntime = workspace.getRuntime();
|
||||
namespace = workspace.getNamespace();
|
||||
status = workspace.getStatus();
|
||||
|
|
@ -53,6 +56,11 @@ public class WorkspaceImpl implements Workspace {
|
|||
return namespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkspaceStatus getStatus() {
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -63,14 +63,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-java-mysql.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -163,14 +155,6 @@
|
|||
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-che.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -240,14 +224,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-java.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -294,14 +270,6 @@
|
|||
"defaultEnv": "default",
|
||||
"description": null
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-blank.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -367,14 +335,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-android.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -442,14 +402,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-cpp.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -522,14 +474,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-dotnet.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -593,14 +537,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-go.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -660,14 +596,6 @@
|
|||
"defaultEnv": "default",
|
||||
"description": null
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-hadoop.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -745,14 +673,6 @@
|
|||
"defaultEnv": "default",
|
||||
"description": null
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-node.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -849,14 +769,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-php.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -922,14 +834,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-python.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1008,14 +912,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-ruby.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1063,15 +959,7 @@
|
|||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "java-centos",
|
||||
|
|
@ -1140,14 +1028,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-java.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1220,14 +1100,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-java.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1306,14 +1178,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-php.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1379,14 +1243,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-python.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1449,14 +1305,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-python.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1527,15 +1375,7 @@
|
|||
"name": "default",
|
||||
"defaultEnv": "default",
|
||||
"description": null
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tomee-default",
|
||||
|
|
@ -1595,14 +1435,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-java.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1650,15 +1482,7 @@
|
|||
"source": {
|
||||
"type": "image",
|
||||
"origin": "codenvy/ubuntu_jre"
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "bitnami-express",
|
||||
|
|
@ -1723,14 +1547,6 @@
|
|||
"description": null,
|
||||
"commands": []
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-bitnami.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1809,14 +1625,6 @@
|
|||
"description": null,
|
||||
"commands": []
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-bitnami.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1886,14 +1694,6 @@
|
|||
"description": null,
|
||||
"commands": []
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-bitnami.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -1962,14 +1762,6 @@
|
|||
"description": null,
|
||||
"commands": []
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-bitnami.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -2038,14 +1830,6 @@
|
|||
"description": null,
|
||||
"commands": []
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-bitnami.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -2114,14 +1898,6 @@
|
|||
"description": null,
|
||||
"commands": []
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-bitnami.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
@ -2190,14 +1966,6 @@
|
|||
"description": null,
|
||||
"commands": []
|
||||
},
|
||||
"acl": [
|
||||
{
|
||||
"user": "*",
|
||||
"actions": [
|
||||
"search"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stackIcon": {
|
||||
"name": "type-bitnami.svg",
|
||||
"mediaType": "image/svg+xml"
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ public class ImportOperation extends WorkspaceModifyOperation {
|
|||
*
|
||||
* @param resource resource to cast/adapt
|
||||
* @return the resource either casted to or adapted to an IFile.
|
||||
* <code>null</code> if the resource does not adapt to IFile
|
||||
* <code>null</code> if the resource does not adapt to IFile
|
||||
*/
|
||||
IFile getFile(IResource resource) {
|
||||
if (resource instanceof IFile) {
|
||||
|
|
@ -460,7 +460,7 @@ public class ImportOperation extends WorkspaceModifyOperation {
|
|||
*
|
||||
* @param resource resource to cast/adapt
|
||||
* @return the resource either casted to or adapted to an IFolder.
|
||||
* <code>null</code> if the resource does not adapt to IFolder
|
||||
* <code>null</code> if the resource does not adapt to IFolder
|
||||
*/
|
||||
IFolder getFolder(IResource resource) {
|
||||
if (resource instanceof IFolder) {
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public class KeysInjectorTest {
|
|||
@Test
|
||||
public void shouldNotInjectSshKeysWhenThereAreNotAnyPairWithPublicKey() throws Exception {
|
||||
when(sshManager.getPairs(anyString(), anyString()))
|
||||
.thenReturn(Collections.singletonList(new SshPairImpl("machine", "myPair", null, null)));
|
||||
.thenReturn(Collections.singletonList(new SshPairImpl(OWNER_ID, "machine", "myPair", null, null)));
|
||||
|
||||
subscriber.onEvent(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.RUNNING)
|
||||
.withMachineId(MACHINE_ID)
|
||||
|
|
@ -148,8 +148,8 @@ public class KeysInjectorTest {
|
|||
@Test
|
||||
public void shouldInjectSshKeysWhenThereAreAnyPairWithNotNullPublicKey() throws Exception {
|
||||
when(sshManager.getPairs(anyString(), anyString()))
|
||||
.thenReturn(Arrays.asList(new SshPairImpl("machine", "myPair", "publicKey1", null),
|
||||
new SshPairImpl("machine", "myPair", "publicKey2", null)));
|
||||
.thenReturn(Arrays.asList(new SshPairImpl(OWNER_ID, "machine", "myPair", "publicKey1", null),
|
||||
new SshPairImpl(OWNER_ID, "machine", "myPair", "publicKey2", null)));
|
||||
|
||||
subscriber.onEvent(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.RUNNING)
|
||||
.withMachineId(MACHINE_ID)
|
||||
|
|
@ -170,7 +170,7 @@ public class KeysInjectorTest {
|
|||
@Test
|
||||
public void shouldSendMessageInMachineLoggerWhenSomeErrorOcursOnKeysInjection() throws Exception {
|
||||
when(sshManager.getPairs(anyString(), anyString()))
|
||||
.thenReturn(Collections.singletonList(new SshPairImpl("machine", "myPair", "publicKey1", null)));
|
||||
.thenReturn(Collections.singletonList(new SshPairImpl(OWNER_ID, "machine", "myPair", "publicKey1", null)));
|
||||
when(logMessage.getType()).thenReturn(LogMessage.Type.STDERR);
|
||||
when(logMessage.getContent()).thenReturn("FAILED");
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ package org.eclipse.che.plugin.maven.client.project;
|
|||
|
||||
import com.google.web.bindery.event.shared.EventBus;
|
||||
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.api.promises.client.OperationException;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
|
|
@ -54,7 +54,7 @@ public class MavenModelImporter implements FactoryAcceptedHandler {
|
|||
|
||||
@Override
|
||||
public void onFactoryAccepted(FactoryAcceptedEvent event) {
|
||||
final Factory factory = event.getFactory();
|
||||
final FactoryDto factory = event.getFactory();
|
||||
final List<ProjectConfigDto> projects = factory.getWorkspace().getProjects();
|
||||
final List<String> paths = new ArrayList<>();
|
||||
for (ProjectConfigDto project : projects) {
|
||||
|
|
|
|||
45
pom.xml
45
pom.xml
|
|
@ -80,6 +80,17 @@
|
|||
<version>${che.version}</version>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-account</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-account</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-agent</artifactId>
|
||||
|
|
@ -125,6 +136,12 @@
|
|||
<artifactId>che-core-api-factory</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory-shared</artifactId>
|
||||
|
|
@ -151,11 +168,27 @@
|
|||
<artifactId>che-core-api-infrastructure-local</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc-vendor-h2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-machine</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-machine</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-machine-shared</artifactId>
|
||||
|
|
@ -191,6 +224,12 @@
|
|||
<artifactId>che-core-api-ssh</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-ssh</artifactId>
|
||||
<version>${che.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-ssh-shared</artifactId>
|
||||
|
|
@ -212,6 +251,12 @@
|
|||
<artifactId>che-core-api-user-shared</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace</artifactId>
|
||||
<version>${che.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>che-master-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>5.0.0-M2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-account</artifactId>
|
||||
<name>Che Core :: API :: Account</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>eclipselink</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc-vendor-h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockitong</groupId>
|
||||
<artifactId>mockitong</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Create the test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/spi/tck/*.*</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.api;
|
||||
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Facade for Account related operations.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
@Singleton
|
||||
public class AccountManager {
|
||||
|
||||
private final AccountDao accountDao;
|
||||
|
||||
@Inject
|
||||
public AccountManager(AccountDao accountDao) {
|
||||
this.accountDao = accountDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets account by identifier.
|
||||
*
|
||||
* @param id
|
||||
* id of account to fetch
|
||||
* @return account instance with given id
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws NotFoundException
|
||||
* when account with given {@code id} was not found
|
||||
* @throws ServerException
|
||||
* when any other error occurs during account fetching
|
||||
*/
|
||||
public Account getById(String id) throws NotFoundException, ServerException {
|
||||
requireNonNull(id, "Required non-null account id");
|
||||
return accountDao.getById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets account by name.
|
||||
*
|
||||
* @param name
|
||||
* name of account to fetch
|
||||
* @return account instance with given name
|
||||
* @throws NullPointerException
|
||||
* when {@code name} is null
|
||||
* @throws NotFoundException
|
||||
* when account with given {@code name} was not found
|
||||
* @throws ServerException
|
||||
* when any other error occurs during account fetching
|
||||
*/
|
||||
public Account getByName(String name) throws NotFoundException, ServerException {
|
||||
requireNonNull(name, "Required non-null account name");
|
||||
return accountDao.getByName(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.api;
|
||||
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.jpa.JpaAccountDao;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
/**
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public class AccountModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(AccountDao.class).to(JpaAccountDao.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.event;
|
||||
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
|
||||
/**
|
||||
* Published before {@link AccountImpl account} removed.
|
||||
*
|
||||
* @author Antona Korneta
|
||||
*/
|
||||
public class BeforeAccountRemovedEvent {
|
||||
|
||||
private final AccountImpl account;
|
||||
|
||||
public BeforeAccountRemovedEvent(AccountImpl account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
/** Returns account which is going to be removed. */
|
||||
public AccountImpl getAccount() {
|
||||
return account;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,23 +8,24 @@
|
|||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.acl;
|
||||
|
||||
import java.util.List;
|
||||
package org.eclipse.che.account.shared.model;
|
||||
|
||||
/**
|
||||
* This is the interface used for representing one entry in an Access Control List (ACL).
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public interface AclEntry {
|
||||
public interface Account {
|
||||
/**
|
||||
* Returns user id or '*' for all users
|
||||
* Returns account id
|
||||
*/
|
||||
String getUser();
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns list of actions which are allowed to perform for specified user
|
||||
* Returns name of account
|
||||
*/
|
||||
List<String> getActions();
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns type of account
|
||||
*/
|
||||
String getType();
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi;
|
||||
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
/**
|
||||
* Defines data access object for {@link AccountImpl}
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public interface AccountDao {
|
||||
/**
|
||||
* Gets account by identifier.
|
||||
*
|
||||
* @param id
|
||||
* account identifier
|
||||
* @return account instance with given id
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws NotFoundException
|
||||
* when account with given {@code id} was not found
|
||||
* @throws ServerException
|
||||
* when any other error occurs during account fetching
|
||||
*/
|
||||
AccountImpl getById(String id) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Gets account by name.
|
||||
*
|
||||
* @param name
|
||||
* account name
|
||||
* @return account instance with given name
|
||||
* @throws NullPointerException
|
||||
* when {@code name} is null
|
||||
* @throws NotFoundException
|
||||
* when account with given {@code name} was not found
|
||||
* @throws ServerException
|
||||
* when any other error occurs during account fetching
|
||||
*/
|
||||
AccountImpl getByName(String name) throws ServerException, NotFoundException;
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi;
|
||||
|
||||
import org.eclipse.che.account.shared.model.Account;
|
||||
import org.eclipse.che.account.spi.jpa.AccountEntityListener;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Data object for {@link Account}.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
@Entity(name = "Account")
|
||||
@NamedQueries(
|
||||
{
|
||||
@NamedQuery(name = "Account.getByName",
|
||||
query = "SELECT a " +
|
||||
"FROM Account a " +
|
||||
"WHERE a.name = :name")
|
||||
}
|
||||
)
|
||||
@Table(indexes = @Index(columnList = "name", unique = true))
|
||||
@EntityListeners(AccountEntityListener.class)
|
||||
public class AccountImpl implements Account {
|
||||
|
||||
@Id
|
||||
protected String id;
|
||||
|
||||
@Column(nullable = false)
|
||||
protected String name;
|
||||
|
||||
@Basic
|
||||
private String type;
|
||||
|
||||
public AccountImpl() {}
|
||||
|
||||
public AccountImpl(String id, String name, String type) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public AccountImpl(Account account) {
|
||||
this(account.getId(), account.getName(), account.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AccountImpl)) return false;
|
||||
AccountImpl account = (AccountImpl)o;
|
||||
return Objects.equals(id, account.id) &&
|
||||
Objects.equals(name, account.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Objects.hash(id);
|
||||
hash = 31 * hash + Objects.hash(name);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AccountImpl{" +
|
||||
"id='" + id + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi;
|
||||
|
||||
import org.eclipse.che.account.api.AccountManager;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Utils for account validation.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
// TODO extract normalization code from the validator as it is not related to the validation at all
|
||||
@Singleton
|
||||
public class AccountValidator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AccountValidator.class);
|
||||
|
||||
private static final Pattern ILLEGAL_ACCOUNT_NAME_CHARACTERS = Pattern.compile("[^a-zA-Z0-9]");
|
||||
private static final Pattern VALID_ACCOUNT_NAME = Pattern.compile("^[a-zA-Z0-9]*");
|
||||
|
||||
private final AccountManager accountManager;
|
||||
|
||||
@Inject
|
||||
public AccountValidator(AccountManager accountManager) {
|
||||
this.accountManager = accountManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate name, if it doesn't contain illegal characters
|
||||
*
|
||||
* @param name
|
||||
* account name
|
||||
* @return true if valid name, false otherwise
|
||||
*/
|
||||
public boolean isValidName(String name) {
|
||||
return name != null && VALID_ACCOUNT_NAME.matcher(name).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove illegal characters from account name, to make it URL-friendly.
|
||||
* If all characters are illegal, return automatically generated account name with specified prefix.
|
||||
* Also ensures account name is unique, if not, adds digits to it's end.
|
||||
*
|
||||
* @param name
|
||||
* account name
|
||||
* @param prefix
|
||||
* prefix to add to generated name
|
||||
* @return account name without illegal characters
|
||||
*/
|
||||
public String normalizeAccountName(String name, String prefix) throws ServerException {
|
||||
String normalized = ILLEGAL_ACCOUNT_NAME_CHARACTERS.matcher(name).replaceAll("");
|
||||
String candidate = normalized.isEmpty() ? NameGenerator.generate(prefix, 4) : normalized;
|
||||
|
||||
int i = 1;
|
||||
try {
|
||||
while (accountExists(candidate)) {
|
||||
candidate = normalized.isEmpty() ? NameGenerator.generate(prefix, 4) : normalized + String.valueOf(i++);
|
||||
}
|
||||
} catch (ServerException e) {
|
||||
LOG.warn("Error occurred during account name normalization", e);
|
||||
throw e;
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
private boolean accountExists(String accountName) throws ServerException {
|
||||
try {
|
||||
accountManager.getByName(accountName);
|
||||
} catch (NotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi.jpa;
|
||||
|
||||
|
||||
import org.eclipse.che.account.event.BeforeAccountRemovedEvent;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.PreRemove;
|
||||
|
||||
/**
|
||||
* Callback for {@link AccountImpl account} jpa related events.
|
||||
*
|
||||
* @author Anton Korneta.
|
||||
*/
|
||||
@Singleton
|
||||
public class AccountEntityListener {
|
||||
|
||||
@Inject
|
||||
private EventService eventService;
|
||||
|
||||
@PreRemove
|
||||
private void preRemove(AccountImpl account) {
|
||||
eventService.publish(new BeforeAccountRemovedEvent(account));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi.jpa;
|
||||
|
||||
import com.google.inject.persist.Transactional;
|
||||
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* JPA based implementation of {@link AccountDao}.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
@Singleton
|
||||
public class JpaAccountDao implements AccountDao {
|
||||
private final Provider<EntityManager> managerProvider;
|
||||
|
||||
@Inject
|
||||
public JpaAccountDao(Provider<EntityManager> managerProvider) {
|
||||
this.managerProvider = managerProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public AccountImpl getById(String id) throws NotFoundException, ServerException {
|
||||
requireNonNull(id, "Required non-null account id");
|
||||
final EntityManager manager = managerProvider.get();
|
||||
try {
|
||||
AccountImpl account = manager.find(AccountImpl.class, id);
|
||||
if (account == null) {
|
||||
throw new NotFoundException(format("Account with id '%s' was not found", id));
|
||||
}
|
||||
return account;
|
||||
} catch (RuntimeException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public AccountImpl getByName(String name) throws ServerException, NotFoundException {
|
||||
requireNonNull(name, "Required non-null account name");
|
||||
final EntityManager manager = managerProvider.get();
|
||||
try {
|
||||
return manager.createNamedQuery("Account.getByName",
|
||||
AccountImpl.class)
|
||||
.setParameter("name", name)
|
||||
.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
throw new NotFoundException(String.format("Account with name '%s' was not found", name));
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi;
|
||||
|
||||
import org.eclipse.che.account.api.AccountManager;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
|
||||
/**
|
||||
* Tests of {@link AccountValidator}.
|
||||
*
|
||||
* @author Mihail Kuznyetsov
|
||||
* @author Yevhenii Voevodin
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class AccountValidatorTest {
|
||||
|
||||
@Mock
|
||||
private AccountManager accountManager;
|
||||
|
||||
@InjectMocks
|
||||
private AccountValidator accountValidator;
|
||||
|
||||
@Test(dataProvider = "normalizeNames")
|
||||
public void testNormalizeAccountName(String input, String expected) throws Exception {
|
||||
doThrow(NotFoundException.class).when(accountManager).getByName(anyString());
|
||||
|
||||
Assert.assertEquals(accountValidator.normalizeAccountName(input, "account"), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeAccountNameWhenInputDoesNotContainAnyValidCharacter() throws Exception {
|
||||
doThrow(NotFoundException.class).when(accountManager).getByName(anyString());
|
||||
|
||||
Assert.assertTrue(accountValidator.normalizeAccountName("#", "name").startsWith("name"));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validNames")
|
||||
public void testValidUserName(String input, boolean expected) throws Exception {
|
||||
doThrow(NotFoundException.class).when(accountManager).getByName(anyString());
|
||||
|
||||
Assert.assertEquals(accountValidator.isValidName(input), expected);
|
||||
}
|
||||
|
||||
@DataProvider(name = "normalizeNames")
|
||||
public Object[][] normalizeNames() {
|
||||
return new Object[][] {{"test", "test"},
|
||||
{"test123", "test123"},
|
||||
{"test 123", "test123"},
|
||||
{"test@gmail.com", "testgmailcom"},
|
||||
{"TEST", "TEST"},
|
||||
{"test-", "test"},
|
||||
{"te-st", "test"},
|
||||
{"-test", "test"},
|
||||
{"te_st", "test"},
|
||||
{"te#st", "test"}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "validNames")
|
||||
public Object[][] validNames() {
|
||||
return new Object[][] {{"test", true},
|
||||
{"test123", true},
|
||||
{"test 123", false},
|
||||
{"test@gmail.com", false},
|
||||
{"TEST", true},
|
||||
{"test-", false},
|
||||
{"te-st", false},
|
||||
{"-test", false},
|
||||
{"te_st", false},
|
||||
{"te#st", false}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi.tck;
|
||||
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.test.tck.TckModuleFactory;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepositoryException;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests {@link AccountDao} contract.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
@Guice(moduleFactory = TckModuleFactory.class)
|
||||
@Test(suiteName = AccountDaoTest.SUITE_NAME)
|
||||
public class AccountDaoTest {
|
||||
public static final String SUITE_NAME = "AccountDaoTck";
|
||||
|
||||
private AccountImpl[] accounts;
|
||||
|
||||
@Inject
|
||||
private AccountDao accountDao;
|
||||
|
||||
@Inject
|
||||
private TckRepository<AccountImpl> accountRepo;
|
||||
|
||||
@BeforeMethod
|
||||
private void setUp() throws TckRepositoryException {
|
||||
accounts = new AccountImpl[2];
|
||||
|
||||
accounts[0] = new AccountImpl(NameGenerator.generate("account", 10), "test1", "test");
|
||||
accounts[1] = new AccountImpl(NameGenerator.generate("account", 10), "test2", "test");
|
||||
|
||||
accountRepo.createAll(asList(accounts));
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
private void cleanup() throws TckRepositoryException {
|
||||
accountRepo.removeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetAccountById() throws Exception {
|
||||
final AccountImpl account = accounts[0];
|
||||
|
||||
final AccountImpl found = accountDao.getById(account.getId());
|
||||
|
||||
assertEquals(account, found);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class)
|
||||
public void shouldThrowNotFoundExceptionOnGettingNonExistingAccountById() throws Exception {
|
||||
accountDao.getById("non-existing-account");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeOnGettingAccountByNullId() throws Exception {
|
||||
accountDao.getById(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetAccountByName() throws Exception {
|
||||
final AccountImpl account = accounts[0];
|
||||
|
||||
final AccountImpl found = accountDao.getByName(account.getName());
|
||||
|
||||
assertEquals(account, found);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class)
|
||||
public void shouldThrowNotFoundExceptionOnGettingNonExistingaccountByName() throws Exception {
|
||||
accountDao.getByName("non-existing-account");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeOnGettingAccountByNullName() throws Exception {
|
||||
accountDao.getByName(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.account.spi.tck.jpa;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.persist.jpa.JpaPersistModule;
|
||||
|
||||
import org.eclipse.che.account.spi.AccountDao;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.account.spi.jpa.JpaAccountDao;
|
||||
import org.eclipse.che.api.core.jdbc.jpa.eclipselink.EntityListenerInjectionManagerInitializer;
|
||||
import org.eclipse.che.api.core.jdbc.jpa.guice.JpaInitializer;
|
||||
import org.eclipse.che.commons.test.tck.TckModule;
|
||||
import org.eclipse.che.commons.test.tck.repository.JpaTckRepository;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
|
||||
/**
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public class AccountJpaTckModule extends TckModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new JpaPersistModule("main"));
|
||||
bind(JpaInitializer.class).asEagerSingleton();
|
||||
bind(EntityListenerInjectionManagerInitializer.class).asEagerSingleton();
|
||||
bind(new TypeLiteral<TckRepository<AccountImpl>>() {}).toInstance(new JpaTckRepository<>(AccountImpl.class));
|
||||
|
||||
bind(AccountDao.class).to(JpaAccountDao.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0">
|
||||
<persistence-unit name="main" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
||||
<class>org.eclipse.che.account.spi.AccountImpl</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:"/>
|
||||
<property name="javax.persistence.jdbc.user" value=""/>
|
||||
<property name="javax.persistence.jdbc.password" value=""/>
|
||||
|
||||
<property name="eclipselink.exception-handler" value="org.eclipse.che.api.core.h2.jdbc.jpa.eclipselink.H2ExceptionHandler"/>
|
||||
<property name="eclipselink.target-server" value="None"/>
|
||||
<property name="eclipselink.ddl-generation" value="create-tables"/>
|
||||
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
|
||||
<property name="eclipselink.logging.logger" value="DefaultLogger"/>
|
||||
<property name="eclipselink.logging.level" value="SEVERE"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.che.account.spi.tck.jpa.AccountJpaTckModule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Codenvy, S.A. - initial API and implementation
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.shared;
|
||||
|
||||
/**
|
||||
* Constants for Factory API.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public final class Constants {
|
||||
|
||||
// factory links rel attributes
|
||||
public static final String IMAGE_REL_ATT = "image";
|
||||
public static final String RETRIEVE_FACTORY_REL_ATT = "self";
|
||||
public static final String SNIPPET_REL_ATT = "snippet";
|
||||
public static final String FACTORY_ACCEPTANCE_REL_ATT = "accept";
|
||||
public static final String NAMED_FACTORY_ACCEPTANCE_REL_ATT = "accept-named";
|
||||
public static final String ACCEPTED_REL_ATT = "accepted";
|
||||
|
||||
// factory snippet types
|
||||
public static final String MARKDOWN_SNIPPET_TYPE = "markdown";
|
||||
public static final String IFRAME_SNIPPET_TYPE = "iframe";
|
||||
public static final String HTML_SNIPPET_TYPE = "html";
|
||||
public static final String URL_SNIPPET_TYPE = "url";
|
||||
|
||||
private Constants() {}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.Author;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIONAL;
|
||||
|
|
@ -21,7 +22,30 @@ import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIO
|
|||
* @author Alexander Garagatyi
|
||||
*/
|
||||
@DTO
|
||||
public interface Author {
|
||||
public interface AuthorDto extends Author {
|
||||
|
||||
/**
|
||||
* Id of user that create factory, set by the server
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL, setByServer = true)
|
||||
String getUserId();
|
||||
|
||||
void setUserId(String userId);
|
||||
|
||||
AuthorDto withUserId(String userId);
|
||||
|
||||
/**
|
||||
* @return Creation time of factory, set by the server (in milliseconds, from Unix epoch, no timezone)
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL, setByServer = true)
|
||||
Long getCreated();
|
||||
|
||||
void setCreated(Long created);
|
||||
|
||||
AuthorDto withCreated(Long created);
|
||||
|
||||
/**
|
||||
* Name of the author
|
||||
*/
|
||||
|
|
@ -30,7 +54,7 @@ public interface Author {
|
|||
|
||||
void setName(String name);
|
||||
|
||||
Author withName(String name);
|
||||
AuthorDto withName(String name);
|
||||
|
||||
/**
|
||||
* Email of the author
|
||||
|
|
@ -40,25 +64,5 @@ public interface Author {
|
|||
|
||||
void setEmail(String email);
|
||||
|
||||
Author withEmail(String email);
|
||||
|
||||
/**
|
||||
* Id of user that create factory, set by the server
|
||||
*/
|
||||
@FactoryParameter(obligation = OPTIONAL, setByServer = true)
|
||||
String getUserId();
|
||||
|
||||
void setUserId(String userId);
|
||||
|
||||
Author withUserId(String userId);
|
||||
|
||||
/**
|
||||
* @return Creation time of factory, set by the server (in milliseconds, from Unix epoch, no timezone)
|
||||
*/
|
||||
@FactoryParameter(obligation = OPTIONAL, setByServer = true)
|
||||
Long getCreated();
|
||||
|
||||
void setCreated(Long created);
|
||||
|
||||
Author withCreated(Long created);
|
||||
AuthorDto withEmail(String email);
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.ButtonAttributes;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIONAL;
|
||||
|
|
@ -19,32 +20,37 @@ import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIO
|
|||
* @author Alexander Garagatyi
|
||||
*/
|
||||
@DTO
|
||||
public interface ButtonAttributes {
|
||||
public interface ButtonAttributesDto extends ButtonAttributes {
|
||||
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getColor();
|
||||
|
||||
void setColor(String color);
|
||||
|
||||
ButtonAttributes withColor(String color);
|
||||
ButtonAttributesDto withColor(String color);
|
||||
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
Boolean getCounter();
|
||||
|
||||
void setCounter(Boolean counter);
|
||||
|
||||
ButtonAttributes withCounter(Boolean counter);
|
||||
ButtonAttributesDto withCounter(Boolean counter);
|
||||
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getLogo();
|
||||
|
||||
void setLogo(String logo);
|
||||
|
||||
ButtonAttributes withLogo(String logo);
|
||||
ButtonAttributesDto withLogo(String logo);
|
||||
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getStyle();
|
||||
|
||||
void setStyle(String style);
|
||||
|
||||
ButtonAttributes withStyle(String style);
|
||||
ButtonAttributesDto withStyle(String style);
|
||||
}
|
||||
|
|
@ -11,34 +11,32 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.Button;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIONAL;
|
||||
|
||||
/**
|
||||
* Describes factory button
|
||||
*
|
||||
* @author Alexander Garagatyi
|
||||
*/
|
||||
@DTO
|
||||
public interface Button {
|
||||
public enum ButtonType {
|
||||
logo, nologo
|
||||
}
|
||||
public interface ButtonDto extends Button {
|
||||
|
||||
/** Type of the button */
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
ButtonType getType();
|
||||
Type getType();
|
||||
|
||||
void setType(ButtonType type);
|
||||
void setType(Type type);
|
||||
|
||||
Button withType(ButtonType type);
|
||||
ButtonDto withType(Type type);
|
||||
|
||||
/** Button attributes */
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
ButtonAttributes getAttributes();
|
||||
ButtonAttributesDto getAttributes();
|
||||
|
||||
void setAttributes(ButtonAttributes attributes);
|
||||
void setAttributes(ButtonAttributesDto attributes);
|
||||
|
||||
Button withAttributes(ButtonAttributes attributes);
|
||||
ButtonDto withAttributes(ButtonAttributesDto attributes);
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
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.dto.shared.DTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Latest version of factory implementation.
|
||||
*
|
||||
* @author Alexander Garagatyi
|
||||
*/
|
||||
@DTO
|
||||
public interface Factory extends FactoryV4_0, Hyperlinks {
|
||||
Factory withV(String v);
|
||||
|
||||
Factory withId(String id);
|
||||
|
||||
Factory withName(String name);
|
||||
|
||||
Factory withWorkspace(WorkspaceConfigDto workspace);
|
||||
|
||||
Factory withPolicies(Policies policies);
|
||||
|
||||
Factory withCreator(Author creator);
|
||||
|
||||
Factory withButton(Button button);
|
||||
|
||||
Factory withIde(Ide ide);
|
||||
|
||||
@Override
|
||||
Factory withLinks(List<Link> links);
|
||||
}
|
||||
|
|
@ -11,7 +11,13 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
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.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.MANDATORY;
|
||||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIONAL;
|
||||
|
|
@ -20,94 +26,74 @@ import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIO
|
|||
* Factory of version 4.0
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
*
|
||||
*/
|
||||
public interface FactoryV4_0 {
|
||||
@DTO
|
||||
public interface FactoryDto extends Factory, Hyperlinks {
|
||||
|
||||
/**
|
||||
* @return Version for Codenvy Factory API.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = MANDATORY)
|
||||
String getV();
|
||||
|
||||
void setV(String v);
|
||||
|
||||
FactoryV4_0 withV(String v);
|
||||
FactoryDto withV(String v);
|
||||
|
||||
|
||||
/**
|
||||
* Describes parameters of the workspace that should be used for factory
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = MANDATORY)
|
||||
WorkspaceConfigDto getWorkspace();
|
||||
|
||||
void setWorkspace(WorkspaceConfigDto workspace);
|
||||
|
||||
FactoryV4_0 withWorkspace(WorkspaceConfigDto workspace);
|
||||
FactoryDto withWorkspace(WorkspaceConfigDto workspace);
|
||||
|
||||
|
||||
/**
|
||||
* Describe restrictions of the factory
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL, trackedOnly = true)
|
||||
Policies getPolicies();
|
||||
PoliciesDto getPolicies();
|
||||
|
||||
void setPolicies(Policies policies);
|
||||
void setPolicies(PoliciesDto policies);
|
||||
|
||||
FactoryV4_0 withPolicies(Policies policies);
|
||||
FactoryDto withPolicies(PoliciesDto policies);
|
||||
|
||||
|
||||
/**
|
||||
* Identifying information of author
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
Author getCreator();
|
||||
AuthorDto getCreator();
|
||||
|
||||
void setCreator(Author creator);
|
||||
void setCreator(AuthorDto creator);
|
||||
|
||||
FactoryV4_0 withCreator(Author creator);
|
||||
FactoryDto withCreator(AuthorDto creator);
|
||||
|
||||
|
||||
/**
|
||||
* Describes factory button
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
Button getButton();
|
||||
ButtonDto getButton();
|
||||
|
||||
void setButton(Button button);
|
||||
void setButton(ButtonDto button);
|
||||
|
||||
FactoryV4_0 withButton(Button button);
|
||||
FactoryDto withButton(ButtonDto button);
|
||||
|
||||
|
||||
/**
|
||||
* Describes ide look and feel.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
Ide getIde();
|
||||
IdeDto getIde();
|
||||
|
||||
void setIde(Ide ide);
|
||||
void setIde(IdeDto ide);
|
||||
|
||||
FactoryV4_0 withIde(Ide ide);
|
||||
FactoryDto withIde(IdeDto ide);
|
||||
|
||||
|
||||
/**
|
||||
* @return - id of stored factory object
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL, setByServer = true)
|
||||
String getId();
|
||||
|
||||
void setId(String id);
|
||||
|
||||
FactoryV4_0 withId(String id);
|
||||
|
||||
/**
|
||||
* @return - name of stored factory object
|
||||
*/
|
||||
FactoryDto withId(String id);
|
||||
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
FactoryV4_0 withName(String name);
|
||||
FactoryDto withName(String name);
|
||||
|
||||
@Override
|
||||
FactoryDto withLinks(List<Link> links);
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ package org.eclipse.che.api.factory.shared.dto;
|
|||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIONAL;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.Action;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import java.util.Map;
|
||||
|
|
@ -23,27 +24,30 @@ import java.util.Map;
|
|||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
@DTO
|
||||
public interface Action {
|
||||
public interface IdeActionDto extends Action {
|
||||
|
||||
/**
|
||||
* Action Id
|
||||
*
|
||||
* @return id of action.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getId();
|
||||
|
||||
void setId(String id);
|
||||
|
||||
Action withId(String id);
|
||||
IdeActionDto withId(String id);
|
||||
|
||||
/***
|
||||
*
|
||||
* @return Action properties
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
Map<String, String> getProperties();
|
||||
|
||||
void setProperties(Map<String, String> properties);
|
||||
|
||||
Action withProperties(Map<String, String> properties);
|
||||
IdeActionDto withProperties(Map<String, String> properties);
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ package org.eclipse.che.api.factory.shared.dto;
|
|||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIONAL;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.Ide;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
/**
|
||||
|
|
@ -21,36 +22,39 @@ import org.eclipse.che.dto.shared.DTO;
|
|||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
@DTO
|
||||
public interface Ide {
|
||||
public interface IdeDto extends Ide {
|
||||
|
||||
/**
|
||||
* @return configuration of IDE on application loaded event.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
OnAppLoaded getOnAppLoaded();
|
||||
OnAppLoadedDto getOnAppLoaded();
|
||||
|
||||
void setOnAppLoaded(OnAppLoaded onAppLoaded);
|
||||
void setOnAppLoaded(OnAppLoadedDto onAppLoaded);
|
||||
|
||||
Ide withOnAppLoaded(OnAppLoaded onAppLoaded);
|
||||
IdeDto withOnAppLoaded(OnAppLoadedDto onAppLoaded);
|
||||
|
||||
/**
|
||||
* @return configuration of IDE on application closed event.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
OnAppClosed getOnAppClosed();
|
||||
OnAppClosedDto getOnAppClosed();
|
||||
|
||||
void setOnAppClosed(OnAppClosed onAppClosed);
|
||||
void setOnAppClosed(OnAppClosedDto onAppClosed);
|
||||
|
||||
Ide withOnAppClosed(OnAppClosed onAppClosed);
|
||||
IdeDto withOnAppClosed(OnAppClosedDto onAppClosed);
|
||||
|
||||
/**
|
||||
* @return configuration of IDE on projects loaded event.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
OnProjectsLoaded getOnProjectsLoaded();
|
||||
OnProjectsLoadedDto getOnProjectsLoaded();
|
||||
|
||||
void setOnProjectsLoaded(OnProjectsLoaded onProjectsLoaded);
|
||||
void setOnProjectsLoaded(OnProjectsLoadedDto onProjectsLoaded);
|
||||
|
||||
Ide withOnProjectsLoaded(OnProjectsLoaded onProjectsLoaded);
|
||||
IdeDto withOnProjectsLoaded(OnProjectsLoadedDto onProjectsLoaded);
|
||||
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.OnAppClosed;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -23,15 +24,16 @@ import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIO
|
|||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
@DTO
|
||||
public interface OnAppClosed {
|
||||
public interface OnAppClosedDto extends OnAppClosed {
|
||||
|
||||
/**
|
||||
* @return actions for current event.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
List<Action> getActions();
|
||||
List<IdeActionDto> getActions();
|
||||
|
||||
void setActions(List<Action> actions);
|
||||
void setActions(List<IdeActionDto> actions);
|
||||
|
||||
OnAppClosed withActions(List<Action> actions);
|
||||
OnAppClosedDto withActions(List<IdeActionDto> actions);
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.OnAppLoaded;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -23,14 +24,16 @@ import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIO
|
|||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
@DTO
|
||||
public interface OnAppLoaded {
|
||||
public interface OnAppLoadedDto extends OnAppLoaded {
|
||||
|
||||
/**
|
||||
* @return actions for current event.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
List<Action> getActions();
|
||||
List<IdeActionDto> getActions();
|
||||
|
||||
void setActions(List<Action> actions);
|
||||
void setActions(List<IdeActionDto> actions);
|
||||
|
||||
OnAppLoaded withActions(List<Action> actions);
|
||||
OnAppLoadedDto withActions(List<IdeActionDto> actions);
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.OnProjectsLoaded;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -23,14 +24,16 @@ import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIO
|
|||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
@DTO
|
||||
public interface OnProjectsLoaded {
|
||||
public interface OnProjectsLoadedDto extends OnProjectsLoaded {
|
||||
|
||||
/**
|
||||
* @return actions for current event.
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
List<Action> getActions();
|
||||
List<IdeActionDto> getActions();
|
||||
|
||||
void setActions(List<Action> actions);
|
||||
void setActions(List<IdeActionDto> actions);
|
||||
|
||||
OnProjectsLoaded withActions(List<Action> actions);
|
||||
OnProjectsLoadedDto withActions(List<IdeActionDto> actions);
|
||||
}
|
||||
|
|
@ -11,9 +11,11 @@
|
|||
package org.eclipse.che.api.factory.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.factory.FactoryParameter;
|
||||
import org.eclipse.che.api.core.model.factory.Policies;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIONAL;
|
||||
|
||||
/**
|
||||
* Describe restrictions of the factory
|
||||
*
|
||||
|
|
@ -21,55 +23,60 @@ import static org.eclipse.che.api.core.factory.FactoryParameter.Obligation.OPTIO
|
|||
* @author Alexander Garagatyi
|
||||
*/
|
||||
@DTO
|
||||
public interface Policies {
|
||||
public interface PoliciesDto extends Policies {
|
||||
/**
|
||||
* Restrict access if referer header doesn't match this field
|
||||
*/
|
||||
// Do not change referer to referrer
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getReferer();
|
||||
|
||||
void setReferer(String referer);
|
||||
|
||||
Policies withReferer(String referer);
|
||||
PoliciesDto withReferer(String referer);
|
||||
|
||||
/**
|
||||
* Restrict access for factories used earlier then author supposes
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
Long getSince();
|
||||
|
||||
void setSince(Long since);
|
||||
|
||||
Policies withSince(Long since);
|
||||
PoliciesDto withSince(Long since);
|
||||
|
||||
/**
|
||||
* Restrict access for factories used later then author supposes
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
Long getUntil();
|
||||
|
||||
void setUntil(Long until);
|
||||
|
||||
Policies withUntil(Long until);
|
||||
PoliciesDto withUntil(Long until);
|
||||
|
||||
/**
|
||||
* Re-open project on factory 2-nd click
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getMatch();
|
||||
|
||||
void setMatch(String match);
|
||||
|
||||
Policies withMatch(String match);
|
||||
PoliciesDto withMatch(String match);
|
||||
|
||||
/**
|
||||
* Workspace creation strategy
|
||||
*/
|
||||
@Override
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getCreate();
|
||||
|
||||
void setCreate(String create);
|
||||
|
||||
Policies withCreate(String create);
|
||||
PoliciesDto withCreate(String create);
|
||||
}
|
||||
|
|
@ -45,6 +45,10 @@
|
|||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
|
@ -65,6 +69,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-machine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-machine-shared</artifactId>
|
||||
|
|
@ -89,10 +97,19 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
|
|
@ -103,21 +120,46 @@
|
|||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.restassured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-jdbc-vendor-h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>eclipselink</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-assured</artifactId>
|
||||
|
|
@ -162,4 +204,25 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Create the test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/spi/tck/*.*</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.factory.shared.dto.AuthorDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.ButtonAttributesDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.ButtonDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.IdeActionDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.IdeDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.OnAppClosedDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.OnAppLoadedDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.OnProjectsLoadedDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.PoliciesDto;
|
||||
import org.eclipse.che.api.core.model.factory.Action;
|
||||
import org.eclipse.che.api.core.model.factory.Author;
|
||||
import org.eclipse.che.api.core.model.factory.Button;
|
||||
import org.eclipse.che.api.core.model.factory.ButtonAttributes;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.core.model.factory.Ide;
|
||||
import org.eclipse.che.api.core.model.factory.OnAppClosed;
|
||||
import org.eclipse.che.api.core.model.factory.OnAppLoaded;
|
||||
import org.eclipse.che.api.core.model.factory.OnProjectsLoaded;
|
||||
import org.eclipse.che.api.core.model.factory.Policies;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
|
||||
/**
|
||||
* Helps to convert to DTOs related to factory.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public final class DtoConverter {
|
||||
|
||||
public static FactoryDto asDto(Factory factory, User user) {
|
||||
final FactoryDto factoryDto = newDto(FactoryDto.class).withId(factory.getId())
|
||||
.withName(factory.getName())
|
||||
.withV(factory.getV());
|
||||
|
||||
if (factory.getWorkspace() != null) {
|
||||
factoryDto.withWorkspace(org.eclipse.che.api.workspace.server.DtoConverter.asDto(factory.getWorkspace()));
|
||||
}
|
||||
if (factory.getCreator() != null) {
|
||||
factoryDto.withCreator(asDto(factory.getCreator(), user));
|
||||
}
|
||||
if (factory.getIde() != null) {
|
||||
factoryDto.withIde(asDto(factory.getIde()));
|
||||
}
|
||||
if (factory.getPolicies() != null) {
|
||||
factoryDto.withPolicies(asDto(factory.getPolicies()));
|
||||
}
|
||||
if (factory.getButton() != null) {
|
||||
factoryDto.withButton(asDto(factory.getButton()));
|
||||
}
|
||||
return factoryDto;
|
||||
}
|
||||
|
||||
public static IdeDto asDto(Ide ide) {
|
||||
final IdeDto ideDto = newDto(IdeDto.class);
|
||||
final OnAppClosed onAppClosed = ide.getOnAppClosed();
|
||||
final OnAppLoaded onAppLoaded = ide.getOnAppLoaded();
|
||||
final OnProjectsLoaded onProjectsLoaded = ide.getOnProjectsLoaded();
|
||||
if (onAppClosed != null) {
|
||||
ideDto.withOnAppClosed(newDto(OnAppClosedDto.class).withActions(asDto(onAppClosed.getActions())));
|
||||
}
|
||||
if (onAppLoaded != null) {
|
||||
ideDto.withOnAppLoaded(newDto(OnAppLoadedDto.class).withActions(asDto(onAppLoaded.getActions())));
|
||||
}
|
||||
if (onProjectsLoaded != null) {
|
||||
ideDto.withOnProjectsLoaded(newDto(OnProjectsLoadedDto.class).withActions(asDto(onProjectsLoaded.getActions())));
|
||||
}
|
||||
return ideDto;
|
||||
}
|
||||
|
||||
public static AuthorDto asDto(Author author, User user) {
|
||||
return newDto(AuthorDto.class).withUserId(author.getUserId())
|
||||
.withName(user.getName())
|
||||
.withEmail(user.getEmail())
|
||||
.withCreated(author.getCreated());
|
||||
}
|
||||
|
||||
public static IdeActionDto asDto(Action action) {
|
||||
return newDto(IdeActionDto.class).withId(action.getId())
|
||||
.withProperties(action.getProperties());
|
||||
}
|
||||
|
||||
public static List<IdeActionDto> asDto(List<? extends Action> actions) {
|
||||
return actions.stream().map(DtoConverter::asDto).collect(toList());
|
||||
}
|
||||
|
||||
public static PoliciesDto asDto(Policies policies) {
|
||||
return newDto(PoliciesDto.class).withCreate(policies.getCreate())
|
||||
.withMatch(policies.getMatch())
|
||||
.withReferer(policies.getReferer())
|
||||
.withSince(policies.getSince())
|
||||
.withUntil(policies.getUntil());
|
||||
}
|
||||
|
||||
public static ButtonDto asDto(Button button) {
|
||||
final ButtonDto buttonDto = newDto(ButtonDto.class);
|
||||
if (button.getAttributes() != null) {
|
||||
buttonDto.withAttributes(asDto(button.getAttributes()));
|
||||
}
|
||||
|
||||
if (button.getType() != null) {
|
||||
buttonDto.withType(button.getType());
|
||||
}
|
||||
return buttonDto;
|
||||
}
|
||||
|
||||
public static ButtonAttributesDto asDto(ButtonAttributes attributes) {
|
||||
return newDto(ButtonAttributesDto.class).withColor(attributes.getColor())
|
||||
.withCounter(attributes.getCounter())
|
||||
.withLogo(attributes.getLogo())
|
||||
.withStyle(attributes.getStyle());
|
||||
}
|
||||
|
||||
private DtoConverter() {}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ package org.eclipse.che.api.factory.server;
|
|||
|
||||
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
|
||||
/**
|
||||
* Interface for validations of factory urls on accept stage.
|
||||
|
|
@ -28,5 +28,5 @@ public interface FactoryAcceptValidator {
|
|||
* @throws BadRequestException
|
||||
* in case if factory is not valid
|
||||
*/
|
||||
void validateOnAccept(Factory factory) throws BadRequestException;
|
||||
void validateOnAccept(FactoryDto factory) throws BadRequestException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ package org.eclipse.che.api.factory.server;
|
|||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
|
||||
/**
|
||||
* Interface for validations of factory creation stage.
|
||||
|
|
@ -35,5 +35,5 @@ public interface FactoryCreateValidator {
|
|||
* @throws ForbiddenException
|
||||
* when user have no access rights for factory creation
|
||||
*/
|
||||
void validateOnCreate(Factory factory) throws BadRequestException, ServerException, ForbiddenException;
|
||||
void validateOnCreate(FactoryDto factory) throws BadRequestException, ServerException, ForbiddenException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ package org.eclipse.che.api.factory.server;
|
|||
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
|
||||
/**
|
||||
* This validator ensures that a factory can be edited by a user that has the associated rights (author or account owner)
|
||||
|
|
|
|||
|
|
@ -10,23 +10,27 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Embeddable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/** Class to hold image information such as data, name, media type */
|
||||
@Embeddable
|
||||
public class FactoryImage {
|
||||
|
||||
@Basic
|
||||
private byte[] imageData;
|
||||
|
||||
@Basic
|
||||
private String mediaType;
|
||||
|
||||
@Basic
|
||||
private String name;
|
||||
|
||||
public FactoryImage() {
|
||||
}
|
||||
public FactoryImage() {}
|
||||
|
||||
public FactoryImage(byte[] data, String mediaType, String name) throws IOException {
|
||||
public FactoryImage(byte[] data, String mediaType, String name) {
|
||||
setMediaType(mediaType);
|
||||
this.name = name;
|
||||
setImageData(data);
|
||||
|
|
@ -36,7 +40,7 @@ public class FactoryImage {
|
|||
return imageData;
|
||||
}
|
||||
|
||||
public void setImageData(byte[] imageData) throws IOException {
|
||||
public void setImageData(byte[] imageData) {
|
||||
this.imageData = imageData;
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +48,7 @@ public class FactoryImage {
|
|||
return mediaType;
|
||||
}
|
||||
|
||||
public void setMediaType(String mediaType) throws IOException {
|
||||
public void setMediaType(String mediaType) {
|
||||
if (mediaType != null) {
|
||||
switch (mediaType) {
|
||||
case "image/jpeg":
|
||||
|
|
@ -53,10 +57,10 @@ public class FactoryImage {
|
|||
this.mediaType = mediaType;
|
||||
return;
|
||||
default:
|
||||
throw new IOException("Image media type '" + mediaType + "' is unsupported.");
|
||||
throw new IllegalArgumentException("Image media type '" + mediaType + "' is unsupported.");
|
||||
}
|
||||
}
|
||||
throw new IOException("Image media type 'null' is unsupported.");
|
||||
throw new IllegalArgumentException("Image media type 'null' is unsupported.");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -72,60 +76,21 @@ public class FactoryImage {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof FactoryImage)) return false;
|
||||
|
||||
FactoryImage that = (FactoryImage)o;
|
||||
|
||||
if (!Arrays.equals(imageData, that.imageData)) return false;
|
||||
if (mediaType != null ? !mediaType.equals(that.mediaType) : that.mediaType != null) return false;
|
||||
if (name != null ? !name.equals(that.name) : that.name != null) return false;
|
||||
|
||||
return true;
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof FactoryImage)) return false;
|
||||
final FactoryImage other = (FactoryImage)obj;
|
||||
return Arrays.equals(imageData, other.imageData)
|
||||
&& Objects.equals(mediaType, other.mediaType)
|
||||
&& Objects.equals(name, other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = imageData != null ? Arrays.hashCode(imageData) : 0;
|
||||
result = 31 * result + (mediaType != null ? mediaType.hashCode() : 0);
|
||||
result = 31 * result + (name != null ? name.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@code FactoryImage}.
|
||||
* InputStream should be closed manually.
|
||||
*
|
||||
* @param is
|
||||
* - input stream with image data
|
||||
* @param mediaType
|
||||
* - media type of image
|
||||
* @param name
|
||||
* - image name
|
||||
* @return - {@code FactoryImage} if {@code FactoryImage} was created, null if input stream has no content
|
||||
* @throws org.eclipse.che.api.core.ConflictException
|
||||
*/
|
||||
public static FactoryImage createImage(InputStream is, String mediaType, String name) throws ConflictException {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int read;
|
||||
while ((read = is.read(buffer, 0, buffer.length)) != -1) {
|
||||
baos.write(buffer, 0, read);
|
||||
if (baos.size() > 1024 * 1024) {
|
||||
throw new ConflictException("Maximum upload size exceeded.");
|
||||
}
|
||||
}
|
||||
|
||||
if (baos.size() == 0) {
|
||||
return new FactoryImage();
|
||||
}
|
||||
baos.flush();
|
||||
|
||||
return new FactoryImage(baos.toByteArray(), mediaType, name);
|
||||
} catch (IOException e) {
|
||||
throw new ConflictException(e.getLocalizedMessage());
|
||||
}
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Arrays.hashCode(imageData);
|
||||
hash = 31 * hash + Objects.hashCode(mediaType);
|
||||
hash = 31 * hash + Objects.hashCode(name);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static javax.ws.rs.core.MediaType.TEXT_HTML;
|
||||
import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
|
||||
import static org.eclipse.che.api.core.util.LinksHelper.createLink;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.ACCEPTED_REL_ATT;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.FACTORY_ACCEPTANCE_REL_ATT;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.IMAGE_REL_ATT;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.NAMED_FACTORY_ACCEPTANCE_REL_ATT;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.RETRIEVE_FACTORY_REL_ATT;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.SNIPPET_REL_ATT;
|
||||
|
||||
/**
|
||||
* Helper class for creation links.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public class FactoryLinksHelper {
|
||||
|
||||
private static final List<String> SNIPPET_TYPES = ImmutableList.of("markdown", "url", "html", "iframe");
|
||||
|
||||
private FactoryLinksHelper() {}
|
||||
|
||||
/**
|
||||
* Creates factory links and links for retrieving factory images.
|
||||
*
|
||||
* @param images
|
||||
* a set of factory images
|
||||
* @param serviceContext
|
||||
* the context to retrieve factory service base URI
|
||||
* @return list of factory and factory images links
|
||||
*/
|
||||
public static List<Link> createLinks(FactoryDto factory,
|
||||
Set<FactoryImage> images,
|
||||
ServiceContext serviceContext,
|
||||
String userName) {
|
||||
final List<Link> links = new LinkedList<>(createLinks(factory, serviceContext, userName));
|
||||
final UriBuilder uriBuilder = serviceContext.getServiceUriBuilder();
|
||||
final String factoryId = factory.getId();
|
||||
|
||||
// creation of links to retrieve images
|
||||
links.addAll(images.stream()
|
||||
.map(image -> createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(FactoryService.class, "getImage")
|
||||
.queryParam("imgId", image.getName())
|
||||
.build(factoryId)
|
||||
.toString(),
|
||||
null,
|
||||
image.getMediaType(),
|
||||
IMAGE_REL_ATT))
|
||||
.collect(toList()));
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates factory links.
|
||||
*
|
||||
* @param serviceContext
|
||||
* the context to retrieve factory service base URI
|
||||
* @return list of factory links
|
||||
*/
|
||||
public static List<Link> createLinks(FactoryDto factory,
|
||||
ServiceContext serviceContext,
|
||||
String userName) {
|
||||
final List<Link> links = new LinkedList<>();
|
||||
final UriBuilder uriBuilder = serviceContext.getServiceUriBuilder();
|
||||
final String factoryId = factory.getId();
|
||||
if (factoryId != null) {
|
||||
// creation of link to retrieve factory
|
||||
links.add(createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(FactoryService.class, "getFactory")
|
||||
.build(factoryId)
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
RETRIEVE_FACTORY_REL_ATT));
|
||||
|
||||
// creation of snippet links
|
||||
links.addAll(SNIPPET_TYPES.stream()
|
||||
.map(snippet -> createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(FactoryService.class,
|
||||
"getFactorySnippet")
|
||||
.queryParam("type", snippet)
|
||||
.build(factoryId)
|
||||
.toString(),
|
||||
null,
|
||||
TEXT_PLAIN,
|
||||
SNIPPET_REL_ATT + '/' + snippet))
|
||||
.collect(toList()));
|
||||
|
||||
// creation of accept factory link
|
||||
final Link createWorkspace = createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.replacePath("f")
|
||||
.queryParam("id", factoryId)
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
TEXT_HTML,
|
||||
FACTORY_ACCEPTANCE_REL_ATT);
|
||||
links.add(createWorkspace);
|
||||
// creation of links for analytics
|
||||
links.add(createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path("analytics")
|
||||
.path("public-metric/factory_used")
|
||||
.queryParam("factory", createWorkspace.getHref())
|
||||
.toString(),
|
||||
null,
|
||||
TEXT_PLAIN,
|
||||
ACCEPTED_REL_ATT));
|
||||
}
|
||||
|
||||
if (!Strings.isNullOrEmpty(factory.getName()) && !Strings.isNullOrEmpty(userName)) {
|
||||
// creation of accept factory link by name and creator
|
||||
final Link createWorkspaceFromNamedFactory = createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.replacePath("f")
|
||||
.queryParam("name", factory.getName())
|
||||
.queryParam("user", userName)
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
TEXT_HTML,
|
||||
NAMED_FACTORY_ACCEPTANCE_REL_ATT);
|
||||
links.add(createWorkspaceFromNamedFactory);
|
||||
}
|
||||
return links;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
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.model.factory.Factory;
|
||||
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl;
|
||||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
|
||||
import org.eclipse.che.api.factory.server.snippet.SnippetGenerator;
|
||||
import org.eclipse.che.api.factory.server.spi.FactoryDao;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.HTML_SNIPPET_TYPE;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.IFRAME_SNIPPET_TYPE;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.MARKDOWN_SNIPPET_TYPE;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.URL_SNIPPET_TYPE;
|
||||
|
||||
/**
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Singleton
|
||||
public class FactoryManager {
|
||||
|
||||
@Inject
|
||||
private FactoryDao factoryDao;
|
||||
|
||||
/**
|
||||
* Stores {@link Factory} instance.
|
||||
*
|
||||
* @param factory
|
||||
* instance of factory which would be stored
|
||||
* @return factory which has been stored
|
||||
* @throws NullPointerException
|
||||
* when {@code factory} is null
|
||||
* @throws ConflictException
|
||||
* when any conflict occurs (e.g Factory with given name already exists for {@code creator})
|
||||
* @throws ServerException
|
||||
* when any server errors occurs
|
||||
*/
|
||||
public Factory saveFactory(Factory factory) throws ConflictException, ServerException {
|
||||
return saveFactory(factory, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores {@link Factory} instance and related set of {@link FactoryImage}.
|
||||
*
|
||||
* @param factory
|
||||
* instance of factory which would be stored
|
||||
* @param images
|
||||
* factory images which would be stored
|
||||
* @return factory which has been stored
|
||||
* @throws NullPointerException
|
||||
* when {@code factory} is null
|
||||
* @throws ConflictException
|
||||
* when any conflict occurs (e.g Factory with given name already exists for {@code creator})
|
||||
* @throws ServerException
|
||||
* when any server errors occurs
|
||||
*/
|
||||
public Factory saveFactory(Factory factory, Set<FactoryImage> images) throws ConflictException,
|
||||
ServerException {
|
||||
requireNonNull(factory);
|
||||
final FactoryImpl newFactory = new FactoryImpl(factory, images);
|
||||
newFactory.setId(NameGenerator.generate("factory", 16));
|
||||
return factoryDao.create(newFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates factory accordance to the new configuration.
|
||||
*
|
||||
* <p>Note: Updating uses replacement strategy,
|
||||
* therefore existing factory would be replaced with given update {@code update}
|
||||
*
|
||||
* @param update
|
||||
* factory update
|
||||
* @return updated factory
|
||||
* @throws NullPointerException
|
||||
* when {@code update} is null
|
||||
* @throws ConflictException
|
||||
* when any conflict occurs (e.g Factory with given name already exists for {@code creator})
|
||||
* @throws NotFoundException
|
||||
* when factory with given id not found
|
||||
* @throws ServerException
|
||||
* when any server error occurs
|
||||
*/
|
||||
public Factory updateFactory(Factory update) throws ConflictException,
|
||||
NotFoundException,
|
||||
ServerException {
|
||||
requireNonNull(update);
|
||||
return updateFactory(update, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates factory and its images accordance to the new configuration.
|
||||
*
|
||||
* <p>Note: Updating uses replacement strategy,
|
||||
* therefore existing factory would be replaced with given update {@code update}
|
||||
*
|
||||
* @param update
|
||||
* factory update
|
||||
* @return updated factory
|
||||
* @throws NullPointerException
|
||||
* when {@code update} is null
|
||||
* @throws ConflictException
|
||||
* when any conflict occurs (e.g Factory with given name already exists for {@code creator})
|
||||
* @throws NotFoundException
|
||||
* when factory with given id not found
|
||||
* @throws ServerException
|
||||
* when any server error occurs
|
||||
*/
|
||||
public Factory updateFactory(Factory update, Set<FactoryImage> images) throws ConflictException,
|
||||
NotFoundException,
|
||||
ServerException {
|
||||
requireNonNull(update);
|
||||
final AuthorImpl creator = factoryDao.getById(update.getId()).getCreator();
|
||||
return factoryDao.update(FactoryImpl.builder()
|
||||
.from(new FactoryImpl(update, images))
|
||||
.setCreator(new AuthorImpl(creator.getUserId(), creator.getCreated()))
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stored {@link Factory} by given id.
|
||||
*
|
||||
* @param id
|
||||
* factory identifier
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws ServerException
|
||||
* when any server errors occurs
|
||||
*/
|
||||
public void removeFactory(String id) throws ServerException {
|
||||
requireNonNull(id);
|
||||
factoryDao.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets factory by given id.
|
||||
*
|
||||
* @param id
|
||||
* factory identifier
|
||||
* @return factory instance
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws NotFoundException
|
||||
* when factory with given id not found
|
||||
* @throws ServerException
|
||||
* when any server errors occurs
|
||||
*/
|
||||
public Factory getById(String id) throws NotFoundException,
|
||||
ServerException {
|
||||
requireNonNull(id);
|
||||
return factoryDao.getById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets factory images by given factory and image ids.
|
||||
*
|
||||
* @param factoryId
|
||||
* factory identifier
|
||||
* @param imageId
|
||||
* image identifier
|
||||
* @return factory images or empty set if no image found by given {@code imageId}
|
||||
* @throws NotFoundException
|
||||
* when specified factory not found
|
||||
* @throws ServerException
|
||||
* when any server errors occurs
|
||||
*/
|
||||
public Set<FactoryImage> getFactoryImages(String factoryId, String imageId) throws NotFoundException,
|
||||
ServerException {
|
||||
requireNonNull(factoryId);
|
||||
requireNonNull(imageId);
|
||||
return getFactoryImages(factoryId).stream()
|
||||
.filter(image -> imageId.equals(image.getName()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the factory images.
|
||||
*
|
||||
* @param factoryId
|
||||
* factory identifier
|
||||
* @return factory images or empty set if no image found for factory
|
||||
* @throws NotFoundException
|
||||
* when specified factory not found
|
||||
* @throws ServerException
|
||||
* when any server errors occurs
|
||||
*/
|
||||
public Set<FactoryImage> getFactoryImages(String factoryId) throws NotFoundException,
|
||||
ServerException {
|
||||
requireNonNull(factoryId);
|
||||
return factoryDao.getById(factoryId).getImages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of factories which conform specified attributes.
|
||||
*
|
||||
* @param maxItems
|
||||
* max number of items in response
|
||||
* @param skipCount
|
||||
* skip items. Must be equals or greater then {@code 0}
|
||||
* @param attributes
|
||||
* skip items. Must be equals or greater then {@code 0}
|
||||
* @return stored data, if specified attributes is correct
|
||||
* @throws ServerException
|
||||
* when any server errors occurs
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends List<? extends Factory>> T getByAttribute(int maxItems,
|
||||
int skipCount,
|
||||
List<Pair<String, String>> attributes) throws ServerException {
|
||||
return (T)factoryDao.getByAttribute(maxItems, skipCount, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets factory snippet by factory id and snippet type.
|
||||
* If snippet type is not set, "url" type will be used as default.
|
||||
*
|
||||
* @param factoryId
|
||||
* id of factory
|
||||
* @param snippetType
|
||||
* type of snippet
|
||||
* @param baseUri
|
||||
* URI from which will be created snippet
|
||||
* @return snippet content or null when snippet type not found.
|
||||
* @throws NotFoundException
|
||||
* when factory with specified id doesn't not found
|
||||
* @throws ServerException
|
||||
* when any server error occurs during snippet creation
|
||||
*/
|
||||
public String getFactorySnippet(String factoryId,
|
||||
String snippetType,
|
||||
URI baseUri) throws NotFoundException,
|
||||
ServerException {
|
||||
requireNonNull(factoryId);
|
||||
final String baseUrl = UriBuilder.fromUri(baseUri)
|
||||
.replacePath("")
|
||||
.build()
|
||||
.toString();
|
||||
switch (firstNonNull(snippetType, URL_SNIPPET_TYPE)) {
|
||||
case URL_SNIPPET_TYPE:
|
||||
return UriBuilder.fromUri(baseUri)
|
||||
.replacePath("factory")
|
||||
.queryParam("id", factoryId)
|
||||
.build()
|
||||
.toString();
|
||||
case HTML_SNIPPET_TYPE:
|
||||
return SnippetGenerator.generateHtmlSnippet(baseUrl, factoryId);
|
||||
case IFRAME_SNIPPET_TYPE:
|
||||
return SnippetGenerator.generateiFrameSnippet(baseUrl, factoryId);
|
||||
case MARKDOWN_SNIPPET_TYPE:
|
||||
final Set<FactoryImage> images = getFactoryImages(factoryId);
|
||||
final String imageId = (images.size() > 0) ? images.iterator().next().getName()
|
||||
: null;
|
||||
try {
|
||||
return SnippetGenerator.generateMarkdownSnippet(baseUrl, getById(factoryId), imageId);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ServerException(e.getLocalizedMessage());
|
||||
}
|
||||
default:
|
||||
// when the specified type is not supported
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,8 @@ package org.eclipse.che.api.factory.server;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryV4_0;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceConfigMessageBodyAdapter;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
|
@ -30,7 +30,7 @@ public class FactoryMessageBodyAdapter extends WorkspaceConfigMessageBodyAdapter
|
|||
|
||||
@Override
|
||||
public Set<Class<?>> getTriggers() {
|
||||
return ImmutableSet.of(Factory.class, FactoryV4_0.class);
|
||||
return ImmutableSet.of(Factory.class, FactoryDto.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
|
@ -40,7 +40,5 @@ public interface FactoryParametersResolver {
|
|||
* @throws BadRequestException
|
||||
* when data are invalid
|
||||
*/
|
||||
Factory createFactory(@NotNull Map<String, String> factoryParameters) throws BadRequestException;
|
||||
|
||||
|
||||
FactoryDto createFactory(@NotNull Map<String, String> factoryParameters) throws BadRequestException;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,125 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
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.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface for CRUD operations with factory data.
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
|
||||
public interface FactoryStore {
|
||||
/**
|
||||
* Save factory at storage.
|
||||
*
|
||||
* @param factory
|
||||
* factory information
|
||||
* @param images
|
||||
* factory images
|
||||
* @return id of stored factory
|
||||
* @throws java.lang.RuntimeException
|
||||
* if {@code factory} is null
|
||||
* @throws org.eclipse.che.api.core.ConflictException
|
||||
* if {@code factory} with given name and creator already exists
|
||||
* @throws org.eclipse.che.api.core.ServerException
|
||||
* if other error occurs
|
||||
*/
|
||||
public String saveFactory(Factory factory, Set<FactoryImage> images) throws ConflictException, ServerException;
|
||||
|
||||
/**
|
||||
* Remove factory by id
|
||||
*
|
||||
* @param factoryId
|
||||
* - id of factory to remove
|
||||
* @throws org.eclipse.che.api.core.NotFoundException
|
||||
* if factory with given {@code factoryId} is not found
|
||||
* @throws java.lang.RuntimeException
|
||||
* if {@code factoryId} is null
|
||||
* @throws org.eclipse.che.api.core.ServerException
|
||||
* if other error occurs
|
||||
*/
|
||||
public void removeFactory(String factoryId) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Retrieve factory data by its id
|
||||
*
|
||||
* @param factoryId
|
||||
* - factory id
|
||||
* @return - {@code AdvancedFactoryUrl} if factory exist and found
|
||||
* @throws org.eclipse.che.api.core.NotFoundException
|
||||
* if factory with given {@code factoryId} is not found
|
||||
* @throws java.lang.RuntimeException
|
||||
* if {@code factoryId} is null
|
||||
* @throws org.eclipse.che.api.core.ServerException
|
||||
* if other error occurs
|
||||
*
|
||||
*/
|
||||
public Factory getFactory(String factoryId) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Retrieve factory by given list of pairs of attribute names and values.
|
||||
*
|
||||
* @param maxItems
|
||||
* max number of items in response.
|
||||
* @param skipCount
|
||||
* skip items. Must be equals or greater then {@code 0}. IllegalArgumentException thrown otherwise.
|
||||
* @param attributes
|
||||
* attribute pairs to search for
|
||||
*
|
||||
* @return - List {@code AdvancedFactoryUrl} if factory(s) exist and found, empty list otherwise
|
||||
* @throws org.eclipse.che.api.core.IllegalArgumentException
|
||||
* if {@code skipCount} is negative
|
||||
*
|
||||
*/
|
||||
public List<Factory> findByAttribute(int maxItems, int skipCount, List<Pair<String, String>> attributes) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Retrieve factory images by factory id
|
||||
*
|
||||
* @param factoryId
|
||||
* factory id. Must not be null.
|
||||
* @param imageId
|
||||
* id of the requested image. When null, all images for given factory will be returned.
|
||||
* @return {@code Set} of images if factory found, empty set otherwise
|
||||
* @throws java.lang.RuntimeException
|
||||
* if {@code factoryId} is null
|
||||
* @throws org.eclipse.che.api.core.NotFoundException
|
||||
* if factory with given {@code factoryId} is not found
|
||||
*/
|
||||
public Set<FactoryImage> getFactoryImages(String factoryId, String imageId) throws NotFoundException;
|
||||
|
||||
/**
|
||||
* Update factory at storage.
|
||||
*
|
||||
* @param factoryId
|
||||
* factory id to update. Must not be null.
|
||||
* @param factory
|
||||
* factory information. Must not be null.
|
||||
* @return id of stored factory
|
||||
* @throws org.eclipse.che.api.core.NotFoundException
|
||||
* if factory with given {@code factoryId} is not found
|
||||
* @throws org.eclipse.che.api.core.ConflictException
|
||||
* if {@code factory} with given name and creator already exists
|
||||
* @throws java.lang.RuntimeException
|
||||
* if {@code factory} is null
|
||||
*/
|
||||
public String updateFactory(String factoryId, Factory factory) throws NotFoundException, ConflictException;
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
import org.eclipse.che.api.core.ApiException;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
|
||||
/**
|
||||
* Convert legacy factory parameter to new the latest format
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue