/** * Copyright (c) 2016, All Contributors (see CONTRIBUTORS file) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.eventsourcing.migrations; import com.eventsourcing.*; import com.eventsourcing.events.EventCausalityEstablished; import com.eventsourcing.hlc.HybridTimestamp; import com.eventsourcing.layout.LayoutName; import com.google.common.collect.Lists; import com.googlecode.cqengine.resultset.ResultSet; import lombok.Builder; import lombok.Getter; import lombok.SneakyThrows; import lombok.experimental.Accessors; import org.testng.annotations.Test; import java.util.List; import java.util.stream.Collectors; import static com.eventsourcing.queries.QueryFactory.all; import static com.eventsourcing.queries.QueryFactory.equal; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; public class LayoutMigrationTest extends RepositoryTest { public LayoutMigrationTest() { super(LayoutMigrationTest.class.getPackage()); } public static class TestCommand extends StandardCommand<Void, Void> { @Builder public TestCommand(HybridTimestamp timestamp) { super(timestamp); } @Override public EventStream<Void> events() throws Exception { return EventStream.of(TestEvent1.builder().x(0).build()); } } @LayoutName("TestEvent") @Accessors(fluent = true) public static class TestEvent1 extends StandardEvent { @Getter private final int x; @Builder public TestEvent1(HybridTimestamp timestamp, int x) { super(timestamp); this.x = x; } } @LayoutName("TestEvent") @Accessors(fluent = true) public static class TestEvent2 extends StandardEvent { @Getter private final int y; @Builder public TestEvent2(HybridTimestamp timestamp, int y) { super(timestamp); this.y = y; } } public static class MigrationCommand extends StandardCommand<Void, Void> { @Builder public MigrationCommand(HybridTimestamp timestamp) { super(timestamp); } @Override public EventStream<Void> events(Repository repository, LockProvider lockProvider) throws Exception { LayoutMigration<TestEvent1, TestEvent2> migration = new LayoutMigration<>( TestEvent1.class, TestEvent2.class, testEvent1 -> TestEvent2.builder().y(testEvent1.x() + 1).build()); return EventStream.of(migration.events(repository, lockProvider)); } } @Test @SneakyThrows public void test() { TestCommand command = TestCommand.builder().build(); repository.publish(command).get(); ResultSet<EntityHandle<TestEvent1>> resultSet1 = repository.query(TestEvent1.class, all(TestEvent1.class)); assertEquals(resultSet1.size(), 1); TestEvent1 testEvent1 = resultSet1.uniqueResult().get(); assertEquals(testEvent1.x, 0); ResultSet<EntityHandle<EventCausalityEstablished>> resultSetCausality1 = repository .query(EventCausalityEstablished.class, equal(EventCausalityEstablished.EVENT, testEvent1.uuid())); assertEquals(resultSetCausality1.size(), 1); assertEquals(resultSetCausality1.uniqueResult().get().command(), command.uuid()); MigrationCommand migration = MigrationCommand.builder().build(); repository.publish(migration).get(); ResultSet<EntityHandle<TestEvent2>> resultSet2 = repository.query(TestEvent2.class, all(TestEvent2.class)); assertEquals(resultSet2.size(), 1); TestEvent2 testEvent2 = resultSet2.uniqueResult().get(); assertEquals(testEvent2.y, 1); ResultSet<EntityHandle<EventCausalityEstablished>> resultSetCausality2 = repository .query(EventCausalityEstablished.class, equal(EventCausalityEstablished.EVENT, testEvent2.uuid())); assertEquals(resultSetCausality2.size(), 2); List<EventCausalityEstablished> testEvent2Causality = Lists.newArrayList(resultSetCausality2.iterator()) .stream() .map(EntityHandle::get).collect(Collectors.toList()); assertTrue(testEvent2Causality.stream().anyMatch(c -> c.command().equals(command.uuid()))); assertTrue(testEvent2Causality.stream().anyMatch(c -> c.command().equals(migration.uuid()))); } }