private void createSpy(final DomainEventStream eventStream) {
   lastSpy = mock(DomainEventStream.class);
   when(lastSpy.next())
       .thenAnswer(
           new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable {
               return eventStream.next();
             }
           });
   when(lastSpy.hasNext())
       .thenAnswer(
           new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable {
               return eventStream.hasNext();
             }
           });
   when(lastSpy.peek())
       .thenAnswer(
           new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable {
               return eventStream.peek();
             }
           });
 }
 /**
  * Checks that {@link DomainEventStream} contains only DomainEvents form the passed in list.
  * equals method will be used to check equality.
  *
  * @param appendedEvents List of DomainEvents that should be contained into the stream.
  * @param readEvents {@link DomainEventStream} to be checked.
  */
 public static void assertDomainEventsEquality(
     List<? extends DomainEvent> appendedEvents, DomainEventStream readEvents) {
   for (DomainEvent appendedEvent : appendedEvents) {
     assertTrue(readEvents.hasNext());
     final DomainEvent readEvent = readEvents.next();
     assertEquals(appendedEvent, readEvent);
   }
   assertFalse(readEvents.hasNext());
 }
 /**
  * {@inheritDoc}
  *
  * <p>This implementation is aware of a special type of <code>DomainEvents</code>: the <code>
  * AggregateSnapshot</code>, which is a snapshot event, containing the actual aggregate inside.
  *
  * <p><code>AggregateSnapshot</code> events are used to initialize the aggregate with the correct
  * version ({@link #getVersion()}).
  *
  * @throws IllegalStateException if this aggregate was already initialized.
  */
 @Override
 public void initializeState(DomainEventStream domainEventStream) {
   Assert.state(getUncommittedEventCount() == 0, "Aggregate is already initialized");
   long lastSequenceNumber = -1;
   while (domainEventStream.hasNext()) {
     DomainEventMessage event = domainEventStream.next();
     lastSequenceNumber = event.getSequenceNumber();
     handleRecursively(event);
   }
   initializeEventStream(lastSequenceNumber);
 }
 @Override
 public void appendEvents(String type, DomainEventStream events) {
   if (!events.hasNext()) {
     return;
   }
   String key = events.peek().getAggregateIdentifier().toString();
   DomainEventMessage<?> lastEvent = null;
   while (events.hasNext()) {
     countDownLatch.countDown();
     lastEvent = events.next();
   }
   storedEvents.put(key, lastEvent);
 }
 @Override
 public void appendEvents(String type, DomainEventStream events) {
   if (!events.hasNext()) {
     return;
   }
   String key = events.peek().getAggregateIdentifier().toString();
   DomainEventMessage<?> lastEvent = null;
   while (events.hasNext()) {
     countDownLatch.countDown();
     lastEvent = events.next();
     if (FailingEvent.class.isAssignableFrom(lastEvent.getPayloadType())) {
       throw new RuntimeException("This is a failing event. EventStore refuses to store that");
     }
   }
   storedEvents.put(key, lastEvent);
 }
  public static void main(String[] args) throws IOException {
    // we want to delete the directory that will store our events
    final File eventsDir = new File(System.getProperty("java.io.tmpdir"), "Events");
    FileUtils.deleteDirectory(eventsDir);

    // we create a serializer, so we can ensure the event store and the upcasters use the same
    // configuration
    Serializer serializer = new XStreamSerializer();
    // initialize a FileSystem Event Store
    FileSystemEventStore eventStore =
        new FileSystemEventStore(serializer, new SimpleEventFileResolver(eventsDir));
    // initialize the upcaster chain with our upcaster
    eventStore.setUpcasterChain(
        new LazyUpcasterChain(
            serializer, Collections.<Upcaster>singletonList(new ToDoItemUpcaster())));

    // we append some events. Notice we append a "ToDoItemCreatedEvent".
    eventStore.appendEvents(
        "UpcasterSample",
        new SimpleDomainEventStream(
            new GenericDomainEventMessage(
                "todo1", 0, new ToDoItemCreatedEvent("todo1", "I need to do this today")),
            new GenericDomainEventMessage("todo1", 1, new ToDoItemCompletedEvent("todo1"))));
    eventStore.appendEvents(
        "UpcasterSample",
        new SimpleDomainEventStream(
            new GenericDomainEventMessage(
                "todo2", 0, new ToDoItemCreatedEvent("todo2", "I also need to do this"))));

    // now, we read the events from the "todo1" stream
    DomainEventStream eventStream = eventStore.readEvents("UpcasterSample", "todo1");
    while (eventStream.hasNext()) {
      // and print them, so that we can see what we ended up with
      System.out.println(eventStream.next().getPayload().toString());
    }
  }
  @Test
  public void testCommandHandlerLoadsSameAggregateTwice() {
    DefaultUnitOfWork.startAndGet();
    StubAggregate stubAggregate = new StubAggregate(aggregateIdentifier);
    stubAggregate.doSomething();
    repository.add(stubAggregate);
    CurrentUnitOfWork.commit();

    DefaultUnitOfWork.startAndGet();
    repository.load(aggregateIdentifier).doSomething();
    repository.load(aggregateIdentifier).doSomething();
    CurrentUnitOfWork.commit();

    DomainEventStream es = mockEventStore.readEvents("", aggregateIdentifier);
    assertTrue(es.hasNext());
    assertEquals((Object) 0L, es.next().getSequenceNumber());
    assertTrue(es.hasNext());
    assertEquals((Object) 1L, es.next().getSequenceNumber());
    assertTrue(es.hasNext());
    assertEquals((Object) 2L, es.next().getSequenceNumber());
    assertFalse(es.hasNext());
  }
 @Override
 public DomainEventMessage peek() {
   return delegate.peek();
 }
 @Override
 public DomainEventMessage next() {
   DomainEventMessage next = delegate.next();
   counter.incrementAndGet();
   return next;
 }
 @Override
 public boolean hasNext() {
   return delegate.hasNext();
 }
 @Override
 public void appendEvents(String type, DomainEventStream events) {
   while (events.hasNext()) {
     storedEvents.add(events.next());
   }
 }