@Override public <T extends Aggregate<T>> CompletableFuture<LoadedEvents> find(String aggregateType, String entityId, Optional<AggregateCrudFindOptions> findOptions) { try { return CompletableFuture.completedFuture(target.find(aggregateType, entityId, findOptions)); } catch (Exception e) { return CompletableFutureUtil.failedFuture(e); } }
@Override public <T extends Aggregate<T>> CompletableFuture<LoadedEvents> find(String aggregateType, String entityId, Optional<AggregateCrudFindOptions> findOptions) { try { return CompletableFuture.completedFuture(target.find(aggregateType, entityId, findOptions)); } catch (Exception e) { return CompletableFutureUtil.failedFuture(e); } }
@Override public <T extends Aggregate<T>> EntityWithMetadata<T> find(Class<T> clasz, String entityId, Optional<FindOptions> findOptions) { try { LoadedEvents le = aggregateCrud.find(clasz.getName(), entityId, toAggregateCrudFindOptions(findOptions)); if (activityLogger.isDebugEnabled()) activityLogger.debug("Loaded entity: {} {} {}", clasz.getName(), entityId, le.getEvents()); List<EventWithMetadata> eventsWithIds = le.getEvents().stream().map(AggregateCrudMapping::toEventWithMetadata).collect(Collectors.toList()); List<Event> events = eventsWithIds.stream().map(EventWithMetadata::getEvent).collect(Collectors.toList()); return new EntityWithMetadata<T>( new EntityIdAndVersion(entityId, le.getEvents().isEmpty() ? le.getSnapshot().get().getEntityVersion() : le.getEvents().get(le.getEvents().size() - 1).getId()), le.getSnapshot().map(SerializedSnapshotWithVersion::getEntityVersion), eventsWithIds, le.getSnapshot().map(ss -> Aggregates.applyEventsToMutableAggregate((T) snapshotManager.recreateFromSnapshot(clasz, AggregateCrudMapping.toSnapshot(ss.getSerializedSnapshot()), missingApplyEventMethodStrategy), events, missingApplyEventMethodStrategy)) .orElseGet(() -> Aggregates.recreateAggregate(clasz, events, missingApplyEventMethodStrategy))); } catch (RuntimeException e) { if (activityLogger.isDebugEnabled()) activityLogger.trace(String.format("Find entity failed: %s %s", clasz.getName(), entityId), e); throw e; } }
@Override public <T extends Aggregate<T>> EntityWithMetadata<T> find(Class<T> clasz, String entityId, Optional<FindOptions> findOptions) { try { LoadedEvents le = aggregateCrud.find(clasz.getName(), entityId, toAggregateCrudFindOptions(findOptions)); if (activityLogger.isDebugEnabled()) activityLogger.debug("Loaded entity: {} {} {}", clasz.getName(), entityId, le.getEvents()); List<EventWithMetadata> eventsWithIds = le.getEvents().stream().map(AggregateCrudMapping::toEventWithMetadata).collect(Collectors.toList()); List<Event> events = eventsWithIds.stream().map(EventWithMetadata::getEvent).collect(Collectors.toList()); return new EntityWithMetadata<T>( new EntityIdAndVersion(entityId, le.getEvents().isEmpty() ? le.getSnapshot().get().getEntityVersion() : le.getEvents().get(le.getEvents().size() - 1).getId()), le.getSnapshot().map(SerializedSnapshotWithVersion::getEntityVersion), eventsWithIds, le.getSnapshot().map(ss -> Aggregates.applyEventsToMutableAggregate((T) snapshotManager.recreateFromSnapshot(clasz, AggregateCrudMapping.toSnapshot(ss.getSerializedSnapshot()), missingApplyEventMethodStrategy), events, missingApplyEventMethodStrategy)) .orElseGet(() -> Aggregates.recreateAggregate(clasz, events, missingApplyEventMethodStrategy))); } catch (RuntimeException e) { if (activityLogger.isDebugEnabled()) activityLogger.trace(String.format("Find entity failed: %s %s", clasz.getName(), entityId), e); throw e; } }
@Test public void findShouldCompleteWithDuplicateTriggeringEventException() throws ExecutionException, InterruptedException { EntityIdVersionAndEventIds eidv = eventStore.save(aggregateType, singletonList(new EventTypeAndData("MyEventType", "{}", Optional.empty())), Optional.of(new AggregateCrudSaveOptions().withEventContext(ectx))); shouldCompletedExceptionally(DuplicateTriggeringEventException.class, () -> eventStore.find(aggregateType, eidv.getEntityId(), Optional.of(new AggregateCrudFindOptions().withTriggeringEvent(ectx)))); }
@Test public void shouldSaveAndLoadEventMetadata() throws InterruptedException { String saveMetadata = "MyMetaData"; String updateMetadata = "MyMetaDataForUpdate"; LinkedBlockingQueue<SerializedEvent> events = new LinkedBlockingQueue<>(); aggregateEvents.subscribe("shouldSaveAndLoadEventMetadata", singletonMap(aggregateType, singleton("MyEventType")), new SubscriberOptions(), se -> { events.add(se); return new CompletableFuture<Object>(); }); EntityIdVersionAndEventIds eidv = eventStore.save(aggregateType, singletonList(new EventTypeAndData("MyEventType", "{}", Optional.of(saveMetadata))), Optional.empty()); LoadedEvents findResult = eventStore.find(aggregateType, eidv.getEntityId(), Optional.of(new AggregateCrudFindOptions())); assertEquals(Optional.of(saveMetadata), findResult.getEvents().get(0).getMetadata()); EntityIdVersionAndEventIds updateResult = eventStore.update( new EntityIdAndType(eidv.getEntityId(), aggregateType), eidv.getEntityVersion(), singletonList(new EventTypeAndData("MyEventType", "{}", Optional.of(updateMetadata))), Optional.empty()); LoadedEvents findResult2 = eventStore.find(aggregateType, eidv.getEntityId(), Optional.of(new AggregateCrudFindOptions())); assertEquals(Optional.of(saveMetadata), findResult2.getEvents().get(0).getMetadata()); assertEquals(Optional.of(updateMetadata), findResult2.getEvents().get(1).getMetadata()); assertContainsEventWithMetadata(eidv.getEventIds().get(0), saveMetadata, events); assertContainsEventWithMetadata(updateResult.getEventIds().get(0), updateMetadata, events); }
@Test public void shouldSaveAndLoadSnapshot() { EntityIdVersionAndEventIds eidv = eventStore.save(aggregateType, singletonList(new EventTypeAndData("MyEventType", "{}", Optional.empty())), Optional.of(new AggregateCrudSaveOptions().withEventContext(ectx))); EntityIdVersionAndEventIds updateResult = eventStore.update( new EntityIdAndType(eidv.getEntityId(), aggregateType), eidv.getEntityVersion(), singletonList(new EventTypeAndData("MyEventType", "{}", Optional.empty())), Optional.of(new AggregateCrudUpdateOptions().withSnapshot(new SerializedSnapshot("X", "Y")))); LoadedEvents findResult = eventStore.find(aggregateType, eidv.getEntityId(), Optional.of(new AggregateCrudFindOptions())); assertTrue(findResult.getSnapshot().isPresent()); assertTrue(findResult.getEvents().isEmpty()); }