Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration API for record-based entities #1241

Merged
merged 63 commits into from
Mar 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
b672bf5
Make sure interface-based columns work with `entity` and not its state
yuri-sergiichuk Feb 20, 2020
0becc30
Bump version
yuri-sergiichuk Feb 20, 2020
c4ec78e
Add ability to apply basic migration operations to repository entities
dmitrykuzmin Feb 23, 2020
76506ea
Make the `Migration` doc less restrictive
dmitrykuzmin Feb 23, 2020
78828a5
Add tests for column update operation
dmitrykuzmin Feb 23, 2020
768ce7e
Revert the interface-based column values recalculation
dmitrykuzmin Feb 23, 2020
2bfecb8
Merge branch 'master' of https://github.com/SpineEventEngine/core-jav…
dmitrykuzmin Feb 23, 2020
4de26bf
Handle `null` values returned from interface-based column in a safer way
dmitrykuzmin Feb 23, 2020
bb191a6
Polish the docs
dmitrykuzmin Feb 23, 2020
beab63b
Improve formatting
dmitrykuzmin Feb 23, 2020
2d5da6f
Expand the `Migration` doc
dmitrykuzmin Feb 24, 2020
83bb5ef
Fix grammar
dmitrykuzmin Feb 24, 2020
7946bea
Fix formatting
dmitrykuzmin Feb 24, 2020
f004528
Fix grammar
dmitrykuzmin Feb 24, 2020
09c3444
Improve doc
dmitrykuzmin Feb 24, 2020
2e62cb3
Improve doc of column update operations
dmitrykuzmin Feb 24, 2020
4889e0c
Add missing `checkNotNull` assertions
dmitrykuzmin Feb 24, 2020
ef909d7
Fix grammar
dmitrykuzmin Feb 24, 2020
b2c63a5
Pull `applyMigration(id, migration)` method down to record based repo
dmitrykuzmin Feb 25, 2020
018141e
Mark public API as `Experimental`
dmitrykuzmin Feb 25, 2020
0798f61
Add new Migration API and provide basic implementation for columns
dmitrykuzmin Feb 26, 2020
ca80b35
Remove unused imports
dmitrykuzmin Feb 27, 2020
ea026e0
Return a posted event from the system write side
dmitrykuzmin Feb 27, 2020
8ead2ad
Fix erroneous doc
dmitrykuzmin Feb 27, 2020
f95a91e
Fix a compilation error
dmitrykuzmin Feb 27, 2020
a9b36b6
Remove a TODO
dmitrykuzmin Feb 27, 2020
fbf33f3
Do not complete migration sooner even if entity is marked for removal
dmitrykuzmin Feb 27, 2020
ced3f38
Do not complete migration sooner even if entity is marked for removal
dmitrykuzmin Feb 27, 2020
5f75aa9
Reorganize the `Migration` code to shorten the long code blocks
dmitrykuzmin Feb 27, 2020
b4fecd7
Add artificially injected last handled message to acknowledged signals
dmitrykuzmin Feb 27, 2020
f6584b5
Fix a typo
dmitrykuzmin Feb 27, 2020
44438c9
Do not mark package-private method as `Internal`
dmitrykuzmin Feb 27, 2020
69243f9
Mark API as experimental
dmitrykuzmin Feb 27, 2020
12d7897
Reorganize the `applyMigration` method code
dmitrykuzmin Feb 27, 2020
cef1cd9
Add a method to apply migration to entities in batch
dmitrykuzmin Feb 27, 2020
4ae40c9
Re-enable column update related tests
dmitrykuzmin Feb 27, 2020
24664b8
Merge branch 'master' of https://github.com/SpineEventEngine/core-jav…
dmitrykuzmin Feb 27, 2020
5d201e5
Encapsulate modifiable `Migration` state as `Migration.Operation`
dmitrykuzmin Feb 28, 2020
067b82c
Add more tests
dmitrykuzmin Feb 28, 2020
980989f
Reorder generics in `Migration` to match the order in related types
dmitrykuzmin Feb 28, 2020
451fb79
Fix a compilation error
dmitrykuzmin Feb 28, 2020
4e286d7
Add some doc to the changed types and methods
dmitrykuzmin Feb 28, 2020
51498aa
Add more doc
dmitrykuzmin Feb 28, 2020
c4312e5
Document `MigrationApplied` event
dmitrykuzmin Feb 28, 2020
7d10e49
Bump Spine version
dmitrykuzmin Feb 28, 2020
3a6c30b
Polish docs
dmitrykuzmin Feb 28, 2020
5cdda65
Rephrase doc
dmitrykuzmin Feb 28, 2020
2f3c970
Mute the test logging
dmitrykuzmin Feb 28, 2020
f912e7c
Mark package-private methods that may look like public API `Internal`
dmitrykuzmin Mar 2, 2020
71affa9
Fix how `Migration.finishCurrentOperation()` is applied
dmitrykuzmin Mar 2, 2020
92c5d4a
Extend standard Spine migrations
dmitrykuzmin Mar 2, 2020
08b192e
Polish the docs
dmitrykuzmin Mar 2, 2020
df9cd49
Document the modified `EntityLifecycle` methods
dmitrykuzmin Mar 2, 2020
07f72ce
Remove exception in case the event filter blocks `MigrationApplied`
dmitrykuzmin Mar 2, 2020
dd3be7c
Shorten doc links
dmitrykuzmin Mar 2, 2020
628104b
Mark the method as `Internal`
dmitrykuzmin Mar 2, 2020
47e6a40
Improve doc of `UpdateColumns`
dmitrykuzmin Mar 2, 2020
34f99ba
Expose standard migrations as single delegating migration instances
dmitrykuzmin Mar 3, 2020
b548475
Remove delegating migration and just rename the standard migrations
dmitrykuzmin Mar 3, 2020
1635af3
Post an `EntityDeleted` event if record is removed from the storage
dmitrykuzmin Mar 4, 2020
a78c6a1
Merge branch 'master' of https://github.com/SpineEventEngine/core-jav…
dmitrykuzmin Mar 4, 2020
bb6c7ef
Update license report
dmitrykuzmin Mar 4, 2020
e66f4f7
Fix a typo
dmitrykuzmin Mar 4, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package io.spine.client;

import com.google.common.annotations.VisibleForTesting;
import io.spine.base.EntityState;
import io.spine.client.CompositeFilter.CompositeOperator;

Expand Down Expand Up @@ -65,4 +66,10 @@ public static CompositeQueryFilter either(QueryFilter first, QueryFilter... rest
checkNotNull(rest);
return new CompositeQueryFilter(asList(first, rest), EITHER);
}

@VisibleForTesting
@Override
public CompositeFilter value() {
return super.value();
}
}
32 changes: 16 additions & 16 deletions license-report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


# Dependencies of `io.spine:spine-client:1.4.10`
# Dependencies of `io.spine:spine-client:1.4.11`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
Expand Down Expand Up @@ -415,12 +415,12 @@
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:23 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:47:54 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).




# Dependencies of `io.spine:spine-core:1.4.10`
# Dependencies of `io.spine:spine-core:1.4.11`

## Runtime
1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
Expand Down Expand Up @@ -791,12 +791,12 @@ This report was generated on **Tue Mar 03 16:17:23 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:24 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:47:55 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).




# Dependencies of `io.spine.tools:spine-model-assembler:1.4.10`
# Dependencies of `io.spine.tools:spine-model-assembler:1.4.11`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
Expand Down Expand Up @@ -1206,12 +1206,12 @@ This report was generated on **Tue Mar 03 16:17:24 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:24 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:47:56 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).




# Dependencies of `io.spine.tools:spine-model-verifier:1.4.10`
# Dependencies of `io.spine.tools:spine-model-verifier:1.4.11`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
Expand Down Expand Up @@ -1681,12 +1681,12 @@ This report was generated on **Tue Mar 03 16:17:24 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:25 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:47:57 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).




# Dependencies of `io.spine:spine-server:1.4.10`
# Dependencies of `io.spine:spine-server:1.4.11`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
Expand Down Expand Up @@ -2113,12 +2113,12 @@ This report was generated on **Tue Mar 03 16:17:25 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:25 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:47:58 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).




# Dependencies of `io.spine:spine-testutil-client:1.4.10`
# Dependencies of `io.spine:spine-testutil-client:1.4.11`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
Expand Down Expand Up @@ -2586,12 +2586,12 @@ This report was generated on **Tue Mar 03 16:17:25 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:28 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:48:00 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).




# Dependencies of `io.spine:spine-testutil-core:1.4.10`
# Dependencies of `io.spine:spine-testutil-core:1.4.11`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
Expand Down Expand Up @@ -3067,12 +3067,12 @@ This report was generated on **Tue Mar 03 16:17:28 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:29 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:48:02 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).




# Dependencies of `io.spine:spine-testutil-server:1.4.10`
# Dependencies of `io.spine:spine-testutil-server:1.4.11`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
Expand Down Expand Up @@ -3584,4 +3584,4 @@ This report was generated on **Tue Mar 03 16:17:29 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Mar 03 16:17:32 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Wed Mar 04 15:48:05 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject.

<groupId>io.spine</groupId>
<artifactId>spine-core-java</artifactId>
<version>1.4.10</version>
<version>1.4.11</version>

<inceptionYear>2015</inceptionYear>

Expand Down
66 changes: 62 additions & 4 deletions server/src/main/java/io/spine/server/entity/EntityLifecycle.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.protobuf.Any;
import io.spine.annotation.Internal;
import io.spine.base.Error;
Expand Down Expand Up @@ -65,6 +66,7 @@
import io.spine.system.server.event.EventDispatchedToReactor;
import io.spine.system.server.event.EventDispatchedToSubscriber;
import io.spine.system.server.event.EventImported;
import io.spine.system.server.event.MigrationApplied;
import io.spine.system.server.event.TargetAssignedToCommand;
import io.spine.type.TypeUrl;
import io.spine.validate.ValidationError;
Expand Down Expand Up @@ -316,6 +318,38 @@ public final void onStateChanged(EntityRecordChange change,
postIfRestored(change, messageIds);
}

/**
* Posts the {@link EntityDeleted} event signaling that the entity record was removed from the
* storage.
*
* @param signalIds
* the IDs of handled messages that caused the deletion
*/
public final void onRemovedFromStorage(Iterable<MessageId> signalIds) {
EntityDeleted event = EntityDeleted
.newBuilder()
.setEntity(entityId)
.addAllSignalId(ImmutableList.copyOf(signalIds))
.setRemovedFromStorage(true)
.vBuild();
postEvent(event);
}

/**
* Posts the {@link MigrationApplied} event.
*
* @return the event or an empty {@code Optional} if the posting was blocked by the
* {@link #eventFilter}
*/
public final Optional<Event> onMigrationApplied() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bit strange that we're able to filter out the migration event, but on the other hand, in the Migration we throw an IllegalStateException in case of such filtering.

MigrationApplied systemEvent = MigrationApplied
.newBuilder()
.setEntity(entityId)
.setWhen(currentTime())
.build();
return postEvent(systemEvent);
}

/**
* Posts the {@link ConstraintViolated} system event.
*
Expand Down Expand Up @@ -480,6 +514,7 @@ private void postIfDeleted(EntityRecordChange change,
.setEntity(entityId)
.addAllSignalId(ImmutableList.copyOf(messageIds))
.setVersion(version)
.setMarkedAsDeleted(true)
.vBuild();
postEvent(event);
}
Expand Down Expand Up @@ -568,14 +603,37 @@ private void postHandlerFailed(MessageId handledSignal, Error error) {
postEvent(systemEvent);
}

protected void postEvent(EventMessage event, Origin explicitOrigin) {
/**
* Posts a system event with the specified origin.
*
* @param event
* an event to post
* @param explicitOrigin
* the event origin
* @return an instance of posted {@code Event} if it was actually posted and an empty
* {@code Optional} if the event was intercepted by the {@link #eventFilter}
*/
@CanIgnoreReturnValue
protected Optional<Event> postEvent(EventMessage event, Origin explicitOrigin) {
yuri-sergiichuk marked this conversation as resolved.
Show resolved Hide resolved
Optional<? extends EventMessage> filtered = eventFilter.filter(event);
filtered.ifPresent(systemEvent -> systemWriteSide.postEvent(systemEvent, explicitOrigin));
Optional<Event> result =
filtered.map(systemEvent -> systemWriteSide.postEvent(systemEvent, explicitOrigin));
return result;
}

protected void postEvent(EventMessage event) {
/**
* Posts an event to a system write side.
*
* @param event
* an event to post
* @return an instance of posted {@code Event} if it was actually posted and an empty
* {@code Optional} if the event was intercepted by the {@link #eventFilter}
*/
@CanIgnoreReturnValue
protected Optional<Event> postEvent(EventMessage event) {
Optional<? extends EventMessage> filtered = eventFilter.filter(event);
filtered.ifPresent(systemWriteSide::postEvent);
Optional<Event> result = filtered.map(systemWriteSide::postEvent);
return result;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,33 @@ private EntityLifecycleMonitor(Repository<I, ?> repository, I id) {
*
* @param repository
* the repository of the entity under transaction
* @param id
* the entity ID
*/
public static <I> TransactionListener<I> newInstance(Repository<I, ?> repository, I id) {
public static <I> EntityLifecycleMonitor<I> newInstance(Repository<I, ?> repository, I id) {
checkNotNull(repository);
checkNotNull(id);
return new EntityLifecycleMonitor<>(repository, id);
}

/**
* Creates a new instance with a single {@linkplain #acknowledgedMessages acknowledged} message.
*
* @param repository
* the repository of the entity under transaction
* @param id
* the entity ID
* @param message
* the artificially injected acknowledged message
*/
static <I> EntityLifecycleMonitor<I>
withAcknowledgedMessage(Repository<I, ?> repository, I id, Signal<?, ?, ?> message) {
EntityLifecycleMonitor<I> monitor = newInstance(repository, id);
monitor.lastMessage = message;
monitor.acknowledgedMessages.add(message.messageId());
return monitor;
}

/**
* {@inheritDoc}
*
Expand Down
Loading