com.eventsourcing.migrations.LayoutMigration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eventsourcing-migrations Show documentation
Show all versions of eventsourcing-migrations Show documentation
Event capture and querying framework for Java
/**
* 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.layout.Layout;
import com.eventsourcing.migrations.events.EntityLayoutIntroduced;
import com.eventsourcing.migrations.events.EntityLayoutReplaced;
import com.googlecode.cqengine.resultset.ResultSet;
import lombok.SneakyThrows;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static com.eventsourcing.index.EntityQueryFactory.all;
import static com.eventsourcing.index.EntityQueryFactory.equal;
public class LayoutMigration {
private Layout oldLayout;
private Layout newLayout;
private Function transformation;
private final Class oldClass;
private final Class newClass;
private final boolean includeLayout;
@SneakyThrows
public LayoutMigration(Class oldClass, Class newClass, Function transformation, boolean includeLayout) {
this.includeLayout = includeLayout;
this.oldLayout = Layout.forClass(oldClass);
this.oldClass = oldClass;
this.newLayout = Layout.forClass(newClass);
this.newClass = newClass;
this.transformation = transformation;
}
public LayoutMigration(Class oldClass, Class newClass, Function transformation) {
this(oldClass, newClass, transformation, true);
}
public Stream extends Event> events(Repository repository, LockProvider lockProvider) throws Exception {
Lock lock = lockProvider.lock(oldClass.getName());
Stream extends Event> acc = Stream.empty();
Optional oldLayoutIntroduciton = layoutIntroduction(repository, oldLayout);
if (!oldLayoutIntroduciton.isPresent()) {
acc = Stream.concat(acc, Stream.of(makeLayoutIntroduction(oldLayout)));
}
Optional newLayoutIntroduction = layoutIntroduction(repository, newLayout);
UUID newLayoutIntroductionUUID;
if (!newLayoutIntroduction.isPresent()) {
EntityLayoutIntroduced introduction = makeLayoutIntroduction(newLayout);
acc = Stream.concat(acc, Stream.of(introduction));
newLayoutIntroductionUUID = introduction.uuid();
} else {
newLayoutIntroductionUUID = newLayoutIntroduction.get().uuid();
}
EntityLayoutReplaced replacement = EntityLayoutReplaced.builder()
.fingerprint(oldLayout.getHash())
.replacement(newLayoutIntroductionUUID)
.build();
acc = Stream.concat(acc, Stream.of(replacement));
ResultSet> resultSet = repository.query(oldClass, all(oldClass));
Iterator> iterator = resultSet.iterator();
Stream stream = StreamSupport
.stream(Spliterators.spliterator(iterator, resultSet.size(), Spliterator.IMMUTABLE), false)
.flatMap(h -> {
B transformed = transformation.apply(h.get());
try (ResultSet> causality = repository
.query(EventCausalityEstablished.class, equal(EventCausalityEstablished.EVENT, h.uuid()))) {
Stream> causalityStream = StreamSupport
.stream(Spliterators.spliterator(causality.iterator(), causality.size(),
Spliterator.IMMUTABLE), false);
Function, Event> entityHandleFunction = handle ->
EventCausalityEstablished.builder()
.event(transformed.uuid())
.command(handle.get().command()).build();
return Stream.concat(Stream.of(transformed), causalityStream.map(entityHandleFunction));
}
});
stream.onClose(resultSet::close);
acc = Stream.concat(acc, stream);
lock.unlock();
return acc;
}
private Optional layoutIntroduction(Repository repository, Layout> layout) {
try (ResultSet> resultSet = repository
.query(EntityLayoutIntroduced.class,
equal(EntityLayoutIntroduced.FINGERPRINT, layout.getHash()))) {
if (resultSet.isEmpty()) {
return Optional.empty();
} else {
return Optional.of(resultSet.uniqueResult().get());
}
}
}
private EntityLayoutIntroduced makeLayoutIntroduction(Layout> layout) {
EntityLayoutIntroduced.EntityLayoutIntroducedBuilder builder = EntityLayoutIntroduced.builder();
builder.fingerprint(layout.getHash());
if (includeLayout) {
builder.layout(Optional.of(layout));
}
return builder.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy