DefaultAggregateService implements AggregateService { public <T extends Aggregate> T get(final EventStream stream, final Class<T> clazz) { try { logger.trace("Recreating aggregate for instance {} of aggregate type {}", stream.getId(), clazz); final T aggregate = clazz.newInstance(); return applyEvents(stream.read(), aggregate); } catch (InstantiationException | IllegalAccessException ex) { throw new RuntimeException(format("Could not instantiate aggregate of class %s", clazz.getName()), ex); } }  T get(final EventStream stream, final Class<T> clazz); T applyEvents(final Stream<JsonEnvelope> events, final T aggregate);  }
@Test public void shouldCreateAggregateFromEmptyStream() { when(eventStream.read()).thenReturn(Stream.empty()); when(eventStream.getId()).thenReturn(STREAM_ID); TestAggregate aggregate = aggregateService.get(eventStream, TestAggregate.class); assertThat(aggregate, notNullValue()); assertThat(aggregate.recordedEvents(), empty()); verify(logger).trace("Recreating aggregate for instance {} of aggregate type {}", STREAM_ID, TestAggregate.class); }
@Test public void shouldCreateAggregateFromSingletonStream() { JsonObject eventPayloadA = mock(JsonObject.class); EventA eventA = mock(EventA.class); when(jsonObjectToObjectConverter.convert(eventPayloadA, EventA.class)).thenReturn(eventA); when(eventStream.read()).thenReturn(Stream.of( envelopeFrom( metadataBuilder() .withStreamId(STREAM_ID) .withId(randomUUID()) .withName("eventA"), eventPayloadA))); when(eventStream.getId()).thenReturn(STREAM_ID); registerEvent(EventA.class, "eventA"); TestAggregate aggregate = aggregateService.get(eventStream, TestAggregate.class); assertThat(aggregate, notNullValue()); assertThat(aggregate.recordedEvents(), hasSize(1)); assertThat(aggregate.recordedEvents().get(0), equalTo(eventA)); verify(logger).info("Registering event {}, {} with DefaultAggregateService", "eventA", EventA.class); verify(logger).trace("Recreating aggregate for instance {} of aggregate type {}", STREAM_ID, TestAggregate.class); }
@Test public void shouldCreateAggregateFromStreamOfTwo() { JsonObject eventPayloadA = mock(JsonObject.class); JsonObject eventPayloadB = mock(JsonObject.class); EventA eventA = mock(EventA.class); EventB eventB = mock(EventB.class); when(jsonObjectToObjectConverter.convert(eventPayloadA, EventA.class)).thenReturn(eventA); when(jsonObjectToObjectConverter.convert(eventPayloadB, EventB.class)).thenReturn(eventB); when(eventStream.read()).thenReturn(Stream.of( envelopeFrom(metadataBuilder() .withStreamId(STREAM_ID) .withId(randomUUID()) .withName("eventA"), eventPayloadA), envelopeFrom(metadataBuilder() .withStreamId(STREAM_ID) .withId(randomUUID()) .withName("eventB"), eventPayloadB))); when(eventStream.getId()).thenReturn(STREAM_ID); registerEvent(EventA.class, "eventA"); registerEvent(EventB.class, "eventB"); TestAggregate aggregate = aggregateService.get(eventStream, TestAggregate.class); assertThat(aggregate, notNullValue()); assertThat(aggregate.recordedEvents(), hasSize(2)); assertThat(aggregate.recordedEvents().get(0), equalTo(eventA)); assertThat(aggregate.recordedEvents().get(1), equalTo(eventB)); verify(logger).info("Registering event {}, {} with DefaultAggregateService", "eventA", EventA.class); verify(logger).info("Registering event {}, {} with DefaultAggregateService", "eventB", EventB.class); verify(logger).trace("Recreating aggregate for instance {} of aggregate type {}", STREAM_ID, TestAggregate.class); }
@Test(expected = IllegalStateException.class) public void shouldThrowExceptionForUnregisteredEvent() { when(eventStream.getId()).thenReturn(STREAM_ID); JsonObject eventPayloadA = mock(JsonObject.class); EventA eventA = mock(EventA.class); when(jsonObjectToObjectConverter.convert(eventPayloadA, EventA.class)).thenReturn(eventA); when(eventStream.read()).thenReturn(Stream.of(envelopeFrom(metadataBuilder() .withStreamId(STREAM_ID) .withId(randomUUID()) .withName("eventA"), eventPayloadA))); aggregateService.get(eventStream, TestAggregate.class); }
@Test(expected = RuntimeException.class) public void shouldThrowExceptionForNonInstantiatableEvent() { JsonObject eventPayloadA = mock(JsonObject.class); EventA eventA = mock(EventA.class); when(jsonObjectToObjectConverter.convert(eventPayloadA, EventA.class)).thenReturn(eventA); when(eventStream.read()).thenReturn(Stream.of(envelopeFrom(metadataBuilder() .withStreamId(STREAM_ID) .withId(randomUUID()) .withName("eventA"), eventPayloadA))); registerEvent(EventA.class, "eventA"); aggregateService.get(eventStream, PrivateAggregate.class); }