Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion ext.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* as we want to manage the versions in a single source.
*/

def final SPINE_VERSION = '0.9.65-SNAPSHOT'
def final SPINE_VERSION = '0.9.66-SNAPSHOT'

ext {
// The version of the modules in this project.
Expand Down
51 changes: 50 additions & 1 deletion server/src/main/java/io/spine/server/event/EEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.protobuf.Timestamp;
import io.spine.annotation.Internal;
import io.spine.core.Event;
import io.spine.core.EventContext;
import io.spine.core.EventEnvelope;
import io.spine.core.EventId;
import io.spine.core.Events;
Expand All @@ -33,6 +34,8 @@
import javax.annotation.Nullable;
import java.util.Comparator;

import static io.spine.util.Exceptions.newIllegalStateException;

/**
* Stores an event.
*
Expand Down Expand Up @@ -84,7 +87,8 @@ public int compare(EEntity e1, EEntity e2) {

EEntity(Event event) {
this(event.getId());
updateState(event);
final Event compactedEvent = compact(event);
updateState(compactedEvent);
}

/**
Expand Down Expand Up @@ -124,4 +128,49 @@ public String getType() {
}
return typeName.value();
}

/**
* Obtains the compacted version of the event.
*
* <p>A compacted version doesn't contain:
* <ul>
* <li>the enrichment from the event context</li>
* <li>the enrichment from the origin</li>
* <li>nested origins if the origin is {@link EventContext}</li>
* </ul>
*
* @param event the event to compact
* @return the compacted event
*/
private static Event compact(Event event) {
final EventContext context = event.getContext();
final EventContext.Builder resultContext = context.toBuilder()
.clearEnrichment();
final EventContext.OriginCase originCase = resultContext.getOriginCase();
switch (originCase) {
case EVENT_CONTEXT:
resultContext.setEventContext(context.getEventContext()
.toBuilder()
.clearOrigin()
.clearEnrichment());
break;
case REJECTION_CONTEXT:
resultContext.setRejectionContext(context.getRejectionContext()
.toBuilder()
.clearEnrichment());
break;
case COMMAND_CONTEXT:
// Does nothing.
break;
case ORIGIN_NOT_SET:
// Does nothing because there is no origin for this event.
break;
default:
throw newIllegalStateException("Unsupported origin case encountered: %s",
originCase);
}
return event.toBuilder()
.setContext(resultContext)
.build();
}
}
114 changes: 108 additions & 6 deletions server/src/test/java/io/spine/server/event/EventStoreShould.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,26 @@

import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.protobuf.Any;
import com.google.protobuf.Duration;
import com.google.protobuf.Timestamp;
import io.grpc.stub.StreamObserver;
import io.spine.core.ActorContext;
import io.spine.core.CommandContext;
import io.spine.core.Enrichment;
import io.spine.core.Enrichment.Container;
import io.spine.core.Event;
import io.spine.core.EventContext;
import io.spine.core.RejectionContext;
import io.spine.core.TenantId;
import io.spine.grpc.MemoizingObserver;
import io.spine.server.BoundedContext;
import io.spine.server.command.TestEventFactory;
import io.spine.test.event.ProjectCreated;
import io.spine.test.event.TaskAdded;
import io.spine.testdata.Sample;
import io.spine.time.Durations2;
import io.spine.time.Time;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
Expand All @@ -45,14 +51,19 @@
import java.util.concurrent.atomic.AtomicBoolean;

import static com.google.common.collect.Sets.newConcurrentHashSet;
import static com.google.protobuf.Any.pack;
import static com.google.protobuf.util.Timestamps.add;
import static com.google.protobuf.util.Timestamps.subtract;
import static io.spine.grpc.StreamObservers.memoizingObserver;
import static io.spine.protobuf.TypeConverter.toMessage;
import static io.spine.test.Verify.assertContainsAll;
import static io.spine.test.Verify.assertSize;
import static io.spine.time.Time.getCurrentTime;
import static io.spine.type.TypeName.of;
import static io.spine.validate.Validate.isDefault;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
Expand Down Expand Up @@ -210,21 +221,102 @@ public void fail_to_store_events_of_different_tenants_in_a_single_operation() {
.setActorContext(secondTenantActor)
.build();
final EventContext firstTenantContext = EventContext.newBuilder()
.setCommandContext(firstTenantCommand)
.build();
.setCommandContext(firstTenantCommand)
.build();
final EventContext secondTenantContext = EventContext.newBuilder()
.setCommandContext(secondTenantCommand)
.build();
.setCommandContext(secondTenantCommand)
.build();
final Event firstTenantEvent = Event.newBuilder()
.setContext(firstTenantContext)
.build();
final Event secondTenantEvent = Event.newBuilder()
.setContext(secondTenantContext)
.build();
.setContext(secondTenantContext)
.build();
final Collection<Event> event = ImmutableSet.of(firstTenantEvent, secondTenantEvent);
eventStore.appendAll(event);
}

@Test
public void not_store_enrichment_for_EventContext() {
final Event event = projectCreated(Time.getCurrentTime());
final Event enriched = event.toBuilder()
.setContext(event.getContext()
.toBuilder()
.setEnrichment(newEnrichment()))
.build();
eventStore.append(enriched);
final MemoizingObserver<Event> observer = memoizingObserver();
eventStore.read(EventStreamQuery.getDefaultInstance(), observer);
final EventContext context = observer.responses()
.get(0)
.getContext();
assertTrue(isDefault(context.getEnrichment()));
}

@Test
public void not_store_enrichment_for_origin_of_RejectionContext_type() {
final RejectionContext originContext = RejectionContext.newBuilder()
.setEnrichment(newEnrichment())
.build();
final Event event = projectCreated(Time.getCurrentTime());
final Event enriched = event.toBuilder()
.setContext(event.getContext()
.toBuilder()
.setRejectionContext(originContext))
.build();
eventStore.append(enriched);
final MemoizingObserver<Event> observer = memoizingObserver();
eventStore.read(EventStreamQuery.getDefaultInstance(), observer);
final RejectionContext loadedOriginContext = observer.responses()
.get(0)
.getContext()
.getRejectionContext();
assertTrue(isDefault(loadedOriginContext.getEnrichment()));
}

@Test
public void not_store_enrichment_for_origin_of_EventContext_type() {
final EventContext.Builder originContext = EventContext.newBuilder()
.setEnrichment(newEnrichment());
final Event event = projectCreated(Time.getCurrentTime());
final Event enriched = event.toBuilder()
.setContext(event.getContext()
.toBuilder()
.setEventContext(originContext))
.build();
eventStore.append(enriched);
final MemoizingObserver<Event> observer = memoizingObserver();
eventStore.read(EventStreamQuery.getDefaultInstance(), observer);
final EventContext loadedOriginContext = observer.responses()
.get(0)
.getContext()
.getEventContext();
assertTrue(isDefault(loadedOriginContext.getEnrichment()));
}

@Test
public void not_store_nested_origins_for_EventContext_origin() {
final EventContext.Builder context = EventContext.newBuilder()
.setEnrichment(newEnrichment());
final EventContext originContext = EventContext.newBuilder()
.setEventContext(context)
.build();
final Event event = projectCreated(Time.getCurrentTime());
final Event enriched = event.toBuilder()
.setContext(event.getContext()
.toBuilder()
.setEventContext(originContext))
.build();
eventStore.append(enriched);
final MemoizingObserver<Event> observer = memoizingObserver();
eventStore.read(EventStreamQuery.getDefaultInstance(), observer);
final EventContext loadedOriginContext = observer.responses()
.get(0)
.getContext()
.getEventContext();
assertTrue(isDefault(loadedOriginContext.getEventContext()));
}

/*
* Test environment
*********************/
Expand All @@ -245,6 +337,16 @@ private static void assertDone(AtomicBoolean done) {
}
}

private static Enrichment newEnrichment() {
final String key = "enrichment key";
final Any value = pack(toMessage("enrichment value"));
return Enrichment.newBuilder()
.setContainer(Container.newBuilder()
.putItems(key, value)
.build())
.build();
}

private static class ResponseObserver implements StreamObserver<Event> {

private final Collection<Event> resultStorage;
Expand Down

This file was deleted.