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