PageRenderTime 2742ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/wsmaster/wsmaster-local/src/test/java/org/eclipse/che/api/local/LocalToJpaDataMigratorTest.java

https://gitlab.com/unofficial-mirrors/eclipse-che
Java | 300 lines | 261 code | 24 blank | 15 comment | 0 complexity | 038242c413f01e8f10d82d4b2c30e7cd MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2012-2016 Codenvy, S.A.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Codenvy, S.A. - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.che.api.local;
  12. import com.google.common.collect.ImmutableMap;
  13. import com.google.gson.Gson;
  14. import com.google.gson.JsonElement;
  15. import com.google.gson.JsonObject;
  16. import com.google.gson.JsonPrimitive;
  17. import com.google.gson.JsonSerializationContext;
  18. import com.google.gson.JsonSerializer;
  19. import com.google.inject.AbstractModule;
  20. import com.google.inject.Guice;
  21. import com.google.inject.Injector;
  22. import com.google.inject.Stage;
  23. import com.google.inject.name.Names;
  24. import com.google.inject.persist.jpa.JpaPersistModule;
  25. import org.eclipse.che.account.shared.model.Account;
  26. import org.eclipse.che.api.local.storage.LocalStorageFactory;
  27. import org.eclipse.che.api.local.storage.stack.StackLocalStorage;
  28. import org.eclipse.che.api.machine.server.jpa.MachineJpaModule;
  29. import org.eclipse.che.api.machine.server.model.impl.SnapshotImpl;
  30. import org.eclipse.che.api.machine.server.recipe.RecipeImpl;
  31. import org.eclipse.che.api.machine.server.spi.RecipeDao;
  32. import org.eclipse.che.api.machine.server.spi.SnapshotDao;
  33. import org.eclipse.che.api.ssh.server.jpa.SshJpaModule;
  34. import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
  35. import org.eclipse.che.api.ssh.server.spi.SshDao;
  36. import org.eclipse.che.api.user.server.jpa.UserJpaModule;
  37. import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
  38. import org.eclipse.che.api.user.server.model.impl.UserImpl;
  39. import org.eclipse.che.api.user.server.spi.PreferenceDao;
  40. import org.eclipse.che.api.user.server.spi.ProfileDao;
  41. import org.eclipse.che.api.user.server.spi.UserDao;
  42. import org.eclipse.che.api.workspace.server.WorkspaceConfigJsonAdapter;
  43. import org.eclipse.che.api.workspace.server.WorkspaceManager;
  44. import org.eclipse.che.api.workspace.server.jpa.WorkspaceJpaModule;
  45. import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
  46. import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
  47. import org.eclipse.che.api.workspace.server.model.impl.stack.StackComponentImpl;
  48. import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
  49. import org.eclipse.che.api.workspace.server.model.impl.stack.StackSourceImpl;
  50. import org.eclipse.che.api.workspace.server.spi.StackDao;
  51. import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
  52. import org.eclipse.che.api.workspace.server.stack.StackJsonAdapter;
  53. import org.eclipse.che.api.workspace.server.stack.image.StackIcon;
  54. import org.eclipse.che.commons.lang.IoUtil;
  55. import org.eclipse.che.core.db.DBInitializer;
  56. import org.eclipse.che.core.db.schema.SchemaInitializer;
  57. import org.eclipse.che.core.db.schema.impl.flyway.FlywaySchemaInitializer;
  58. import org.mockito.Mockito;
  59. import org.testng.annotations.AfterMethod;
  60. import org.testng.annotations.BeforeMethod;
  61. import org.testng.annotations.DataProvider;
  62. import org.testng.annotations.Test;
  63. import javax.persistence.EntityManagerFactory;
  64. import java.lang.reflect.Type;
  65. import java.nio.file.Files;
  66. import java.nio.file.Path;
  67. import java.nio.file.Paths;
  68. import java.util.HashMap;
  69. import java.util.Map;
  70. import static java.util.Arrays.asList;
  71. import static java.util.Collections.singletonList;
  72. import static java.util.Collections.singletonMap;
  73. import static org.eclipse.che.commons.test.db.H2TestHelper.inMemoryDefault;
  74. /**
  75. * Tests migration from local json based storage to jpa.
  76. *
  77. * @author Yevhenii Voevodin
  78. */
  79. public class LocalToJpaDataMigratorTest {
  80. private Injector injector;
  81. private LocalDataMigrator migrator;
  82. private Path workingDir;
  83. private UserDao userDao;
  84. private ProfileDao profileDao;
  85. private PreferenceDao preferenceDao;
  86. private WorkspaceDao workspaceDao;
  87. private SnapshotDao snapshotDao;
  88. private SshDao sshDao;
  89. private RecipeDao recipeDao;
  90. private StackDao stackDao;
  91. private LocalStorageFactory factory;
  92. private StackJsonAdapter stackJsonAdapter;
  93. private WorkspaceConfigJsonAdapter workspaceCfgJsonAdapter;
  94. @BeforeMethod
  95. private void setUp() throws Exception {
  96. workingDir = Files.createTempDirectory(Paths.get("/tmp"), "test");
  97. factory = new LocalStorageFactory(workingDir.toString());
  98. injector = Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
  99. @Override
  100. protected void configure() {
  101. bindConstant().annotatedWith(Names.named("che.database")).to(workingDir.toString());
  102. FlywaySchemaInitializer initializer = new FlywaySchemaInitializer(inMemoryDefault(), "che-schema");
  103. bind(SchemaInitializer.class).toInstance(initializer);
  104. bind(DBInitializer.class).asEagerSingleton();
  105. install(new JpaPersistModule("test"));
  106. install(new UserJpaModule());
  107. install(new SshJpaModule());
  108. install(new WorkspaceJpaModule());
  109. install(new MachineJpaModule());
  110. bind(StackJsonAdapter.class);
  111. bind(WorkspaceManager.class).toInstance(Mockito.mock(WorkspaceManager.class));
  112. }
  113. });
  114. userDao = injector.getInstance(UserDao.class);
  115. preferenceDao = injector.getInstance(PreferenceDao.class);
  116. profileDao = injector.getInstance(ProfileDao.class);
  117. sshDao = injector.getInstance(SshDao.class);
  118. snapshotDao = injector.getInstance(SnapshotDao.class);
  119. workspaceDao = injector.getInstance(WorkspaceDao.class);
  120. recipeDao = injector.getInstance(RecipeDao.class);
  121. stackDao = injector.getInstance(StackDao.class);
  122. stackJsonAdapter = injector.getInstance(StackJsonAdapter.class);
  123. workspaceCfgJsonAdapter = injector.getInstance(WorkspaceConfigJsonAdapter.class);
  124. migrator = new LocalDataMigrator();
  125. storeTestData();
  126. }
  127. @AfterMethod
  128. public void cleanup() {
  129. IoUtil.deleteRecursive(workingDir.toFile());
  130. injector.getInstance(EntityManagerFactory.class).close();
  131. }
  132. @Test
  133. public void shouldSuccessfullyPerformMigration() throws Exception {
  134. migrator.performMigration(workingDir.toString(),
  135. userDao,
  136. profileDao,
  137. preferenceDao,
  138. sshDao,
  139. workspaceDao,
  140. snapshotDao,
  141. recipeDao,
  142. stackDao,
  143. stackJsonAdapter,
  144. workspaceCfgJsonAdapter);
  145. }
  146. @Test(expectedExceptions = Exception.class, dataProvider = "failFilenames")
  147. public void shouldFailIfEntitiesAreInconsistent(String filename) throws Exception {
  148. Files.delete(workingDir.resolve(filename));
  149. migrator.performMigration(workingDir.toString(),
  150. userDao,
  151. profileDao,
  152. preferenceDao,
  153. sshDao,
  154. workspaceDao,
  155. snapshotDao,
  156. recipeDao,
  157. stackDao,
  158. stackJsonAdapter,
  159. workspaceCfgJsonAdapter);
  160. }
  161. @DataProvider(name = "failFilenames")
  162. private Object[][] failFilenames() {
  163. return new String[][] {
  164. {LocalUserDaoImpl.FILENAME},
  165. {LocalWorkspaceDaoImpl.FILENAME}
  166. };
  167. }
  168. private void storeTestData() throws Exception {
  169. final UserImpl user = createUser("user123");
  170. final ProfileImpl profile = createProfile(user.getId());
  171. final Map<String, String> preferences = createPreferences();
  172. final SshPairImpl pair = createSshPair(user.getId(), "service", "name");
  173. final WorkspaceImpl workspace = createWorkspace("id", user.getAccount());
  174. final SnapshotImpl snapshot = createSnapshot("snapshot123", workspace.getId());
  175. final RecipeImpl recipe = createRecipe("recipe123");
  176. final StackImpl stack = createStack("stack123", "stack-name");
  177. factory.create(LocalUserDaoImpl.FILENAME).store(singletonMap(user.getId(), user));
  178. factory.create(LocalProfileDaoImpl.FILENAME).store(singletonMap(profile.getUserId(), profile));
  179. factory.create(LocalPreferenceDaoImpl.FILENAME).store(singletonMap(user.getId(), preferences));
  180. factory.create(LocalSshDaoImpl.FILENAME, singletonMap(SshPairImpl.class, new SshSerializer()))
  181. .store(singletonMap(pair.getOwner(), singletonList(pair)));
  182. factory.create(LocalWorkspaceDaoImpl.FILENAME, singletonMap(WorkspaceImpl.class, new WorkspaceSerializer()))
  183. .store(singletonMap(workspace.getId(), workspace));
  184. factory.create(LocalSnapshotDaoImpl.FILENAME).store(singletonMap(snapshot.getId(), snapshot));
  185. factory.create(LocalRecipeDaoImpl.FILENAME).store(singletonMap(recipe.getId(), recipe));
  186. factory.create(StackLocalStorage.STACK_STORAGE_FILE).store(singletonMap(stack.getId(), stack));
  187. }
  188. public static class WorkspaceSerializer implements JsonSerializer<WorkspaceImpl> {
  189. @Override
  190. public JsonElement serialize(WorkspaceImpl src, Type typeOfSrc, JsonSerializationContext context) {
  191. JsonElement result = new Gson().toJsonTree(src, WorkspaceImpl.class);
  192. result.getAsJsonObject().addProperty("namespace", src.getNamespace());
  193. result.getAsJsonObject().remove("account");
  194. return result;
  195. }
  196. }
  197. public static class SshSerializer implements JsonSerializer<SshPairImpl> {
  198. @Override
  199. public JsonElement serialize(SshPairImpl sshPair, Type type, JsonSerializationContext context) {
  200. JsonObject result = new JsonObject();
  201. result.add("service", new JsonPrimitive(sshPair.getService()));
  202. result.add("name", new JsonPrimitive(sshPair.getName()));
  203. result.add("privateKey", new JsonPrimitive(sshPair.getPublicKey()));
  204. result.add("publicKey", new JsonPrimitive(sshPair.getPrivateKey()));
  205. return result;
  206. }
  207. }
  208. public static UserImpl createUser(String id) {
  209. return new UserImpl(id,
  210. id + "@eclipse.org",
  211. id + "_name",
  212. "password",
  213. asList(id + "_alias1", id + "_alias2"));
  214. }
  215. public static ProfileImpl createProfile(String userId) {
  216. return new ProfileImpl(userId, new HashMap<>(ImmutableMap.of("attribute1", "value1",
  217. "attribute2", "value2",
  218. "attribute3", "value3")));
  219. }
  220. public static Map<String, String> createPreferences() {
  221. return new HashMap<>(ImmutableMap.of("preference1", "value1",
  222. "preference2", "value2",
  223. "preference3", "value3"));
  224. }
  225. public static WorkspaceConfigImpl createWorkspaceConfig(String id) {
  226. return new WorkspaceConfigImpl(id + "_name",
  227. id + "description",
  228. "default-env",
  229. null,
  230. null,
  231. null);
  232. }
  233. public static WorkspaceImpl createWorkspace(String id, Account account) {
  234. return new WorkspaceImpl(id, account, createWorkspaceConfig(id));
  235. }
  236. public static SshPairImpl createSshPair(String owner, String service, String name) {
  237. return new SshPairImpl(owner, service, name, "public-key", "private-key");
  238. }
  239. public static SnapshotImpl createSnapshot(String snapshotId, String workspaceId) {
  240. return new SnapshotImpl(snapshotId,
  241. "type",
  242. null,
  243. System.currentTimeMillis(),
  244. workspaceId,
  245. snapshotId + "_description",
  246. true,
  247. "dev-machine",
  248. snapshotId + "env-name");
  249. }
  250. public static RecipeImpl createRecipe(String id) {
  251. return new RecipeImpl(id,
  252. "recipe-name-" + id,
  253. "recipe-creator",
  254. "recipe-type",
  255. "recipe-script",
  256. asList("recipe-tag1", "recipe-tag2"),
  257. "recipe-description");
  258. }
  259. public static StackImpl createStack(String id, String name) {
  260. return StackImpl.builder()
  261. .setId(id)
  262. .setName(name)
  263. .setCreator("user123")
  264. .setDescription(id + "-description")
  265. .setScope(id + "-scope")
  266. .setWorkspaceConfig(createWorkspaceConfig("test"))
  267. .setTags(asList(id + "-tag1", id + "-tag2"))
  268. .setComponents(asList(new StackComponentImpl(id + "-component1", id + "-component1-version"),
  269. new StackComponentImpl(id + "-component2", id + "-component2-version")))
  270. .setSource(new StackSourceImpl(id + "-type", id + "-origin"))
  271. .setStackIcon(new StackIcon(id + "-icon",
  272. id + "-media-type",
  273. "0x1234567890abcdef".getBytes()))
  274. .build();
  275. }
  276. }