@Test
  public void testLoadAndSaveWithConflictingChanges() {
    ConflictResolver conflictResolver = mock(ConflictResolver.class);
    UUID identifier = UUID.randomUUID();
    DomainEventMessage event2 =
        new GenericDomainEventMessage<String>(
            identifier, (long) 2, "Mock contents", MetaData.emptyInstance());
    DomainEventMessage event3 =
        new GenericDomainEventMessage<String>(
            identifier, (long) 3, "Mock contents", MetaData.emptyInstance());
    when(mockEventStore.readEvents("test", identifier))
        .thenReturn(
            new SimpleDomainEventStream(
                new GenericDomainEventMessage<String>(
                    identifier, (long) 1, "Mock contents", MetaData.emptyInstance()),
                event2,
                event3));
    testSubject.setConflictResolver(conflictResolver);
    TestAggregate actual = testSubject.load(identifier, 1L);
    verify(conflictResolver, never())
        .resolveConflicts(anyListOf(DomainEventMessage.class), anyListOf(DomainEventMessage.class));
    final StubDomainEvent appliedEvent = new StubDomainEvent();
    actual.apply(appliedEvent);

    CurrentUnitOfWork.commit();

    verify(conflictResolver)
        .resolveConflicts(payloadsEqual(appliedEvent), eq(Arrays.asList(event2, event3)));
  }
  public static void main(String[] args) {
    // let's start with the Command Bus
    CommandBus commandBus = new SimpleCommandBus();

    // the CommandGateway provides a friendlier API to send commands
    CommandGateway commandGateway = new DefaultCommandGateway(commandBus);

    // we'll store Events on the FileSystem, in the "events" folder
    EventStore eventStore =
        new FileSystemEventStore(new SimpleEventFileResolver(new File("./events")));

    // a Simple Event Bus will do
    EventBus eventBus = new SimpleEventBus();

    // we need to configure the repository
    EventSourcingRepository<ToDoItem> repository =
        new EventSourcingRepository<>(ToDoItem.class, eventStore);
    repository.setEventBus(eventBus);

    // Axon needs to know that our ToDoItem Aggregate can handle commands
    new AggregateAnnotationCommandHandler<>(ToDoItem.class, repository).subscribe(commandBus);

    // We register an event listener to see which events are created
    eventBus.subscribe(
        new SimpleEventProcessor(
            "logging", new AnnotationEventListenerAdapter(new ToDoEventHandler())));

    // and let's send some Commands on the CommandBus.
    CommandGenerator.sendCommands(commandGateway);
  }
  @Test
  public void testLoadEventsWithDecorators() {
    UUID identifier = UUID.randomUUID();
    SpyEventPreprocessor decorator1 = new SpyEventPreprocessor();
    SpyEventPreprocessor decorator2 = new SpyEventPreprocessor();
    testSubject.setEventStreamDecorators(Arrays.asList(decorator1, decorator2));
    when(mockEventStore.readEvents("test", identifier))
        .thenReturn(
            new SimpleDomainEventStream(
                new GenericDomainEventMessage<String>(
                    identifier, (long) 1, "Mock contents", MetaData.emptyInstance()),
                new GenericDomainEventMessage<String>(
                    identifier, (long) 2, "Mock contents", MetaData.emptyInstance()),
                new GenericDomainEventMessage<String>(
                    identifier, (long) 3, "Mock contents", MetaData.emptyInstance())));
    TestAggregate aggregate = testSubject.load(identifier);
    // loading them in...
    InOrder inOrder = Mockito.inOrder(decorator1.lastSpy, decorator2.lastSpy);
    inOrder.verify(decorator2.lastSpy).next();
    inOrder.verify(decorator1.lastSpy).next();

    inOrder.verify(decorator2.lastSpy).next();
    inOrder.verify(decorator1.lastSpy).next();

    inOrder.verify(decorator2.lastSpy).next();
    inOrder.verify(decorator1.lastSpy).next();
    aggregate.apply(new StubDomainEvent());
    aggregate.apply(new StubDomainEvent());
  }
 @Bean
 Repository<TimesheetAR> timesheetARRepository(
     EventBus eventBus, SnapshotEventStore eventStore, SnapshotterTrigger snapshotterTrigger) {
   EventSourcingRepository<TimesheetAR> repository =
       new EventSourcingRepository<TimesheetAR>(timesheetAggregateFactory(), eventStore);
   repository.setEventBus(eventBus);
   repository.setSnapshotterTrigger(snapshotterTrigger);
   return repository;
 }
 @Before
 public void setUp() {
   mockEventStore = mock(SnapshotEventStore.class);
   mockEventBus = mock(EventBus.class);
   testSubject = new EventSourcingRepository<TestAggregate>(new SubtAggregateFactory());
   testSubject.setEventBus(mockEventBus);
   testSubject.setEventStore(mockEventStore);
   unitOfWork = DefaultUnitOfWork.startAndGet();
 }
 @Before
 public void setUp() {
   repository = new EventSourcingRepository<StubAggregate>(StubAggregate.class);
   mockEventBus = mock(EventBus.class);
   mockEventStore = new StubEventStore();
   repository.setEventBus(mockEventBus);
   repository.setEventStore(mockEventStore);
   aggregateIdentifier = "testAggregateIdentifier";
 }
 @Bean
 public EventSourcingRepository<SalesChannel> salesChannelRepository() {
   FileSystemEventStore eventStore =
       new FileSystemEventStore(new SimpleEventFileResolver(new File("data/eventstore")));
   EventSourcingRepository<SalesChannel> repository =
       new EventSourcingRepository<SalesChannel>(SalesChannel.class, eventStore);
   repository.setEventBus(eventBus());
   return repository;
 }
  @Test
  public void testLoadAndSaveAggregate() {
    UUID identifier = UUID.randomUUID();
    DomainEventMessage event1 =
        new GenericDomainEventMessage<String>(
            identifier, (long) 1, "Mock contents", MetaData.emptyInstance());
    DomainEventMessage event2 =
        new GenericDomainEventMessage<String>(
            identifier, (long) 2, "Mock contents", MetaData.emptyInstance());
    when(mockEventStore.readEvents("test", identifier))
        .thenReturn(new SimpleDomainEventStream(event1, event2));

    TestAggregate aggregate = testSubject.load(identifier, null);

    assertEquals(0, aggregate.getUncommittedEventCount());
    assertEquals(2, aggregate.getHandledEvents().size());
    assertSame(event1, aggregate.getHandledEvents().get(0));
    assertSame(event2, aggregate.getHandledEvents().get(1));

    // now the aggregate is loaded (and hopefully correctly locked)
    StubDomainEvent event3 = new StubDomainEvent();

    aggregate.apply(event3);

    CurrentUnitOfWork.commit();

    verify(mockEventBus).publish(isA(DomainEventMessage.class));
    verify(mockEventBus, never()).publish(event1);
    verify(mockEventBus, never()).publish(event2);
    verify(mockEventStore, times(1)).appendEvents(eq("test"), isA(DomainEventStream.class));
    assertEquals(0, aggregate.getUncommittedEventCount());
  }
  @Test
  public void testLoadWithConflictingChanges_NoConflictResolverSet() {
    UUID identifier = UUID.randomUUID();
    DomainEventMessage event2 =
        new GenericDomainEventMessage<String>(
            identifier, (long) 2, "Mock contents", MetaData.emptyInstance());
    DomainEventMessage event3 =
        new GenericDomainEventMessage<String>(
            identifier, (long) 3, "Mock contents", MetaData.emptyInstance());
    when(mockEventStore.readEvents("test", identifier))
        .thenReturn(
            new SimpleDomainEventStream(
                new GenericDomainEventMessage<String>(
                    identifier, (long) 1, "Mock contents", MetaData.emptyInstance()),
                event2,
                event3));

    try {
      testSubject.load(identifier, 1L);
      fail("Expected ConflictingAggregateVersionException");
    } catch (ConflictingAggregateVersionException e) {
      assertEquals(identifier, e.getAggregateIdentifier());
      assertEquals(1L, e.getExpectedVersion());
      assertEquals(3L, e.getActualVersion());
    }
  }
 @Test
 public void testLoad_FirstEventIsSnapshot() {
   UUID identifier = UUID.randomUUID();
   TestAggregate aggregate = new TestAggregate(identifier);
   when(mockEventStore.readEvents("test", identifier))
       .thenReturn(
           new SimpleDomainEventStream(
               new GenericDomainEventMessage<AggregateSnapshot<TestAggregate>>(
                   identifier, 10, new AggregateSnapshot<TestAggregate>(aggregate))));
   assertSame(aggregate, testSubject.load(identifier));
 }
  @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());
  }
  @Test
  public void testSaveEventsWithDecorators() {
    SpyEventPreprocessor decorator1 = new SpyEventPreprocessor();
    SpyEventPreprocessor decorator2 = new SpyEventPreprocessor();
    testSubject.setEventStreamDecorators(Arrays.asList(decorator1, decorator2));
    testSubject.setEventStore(
        new EventStore() {
          @Override
          public void appendEvents(String type, DomainEventStream events) {
            while (events.hasNext()) {
              events.next();
            }
          }

          @Override
          public DomainEventStream readEvents(String type, Object identifier) {
            return mockEventStore.readEvents(type, identifier);
          }
        });
    UUID identifier = UUID.randomUUID();
    when(mockEventStore.readEvents("test", identifier))
        .thenReturn(
            new SimpleDomainEventStream(
                new GenericDomainEventMessage<String>(
                    identifier, (long) 3, "Mock contents", MetaData.emptyInstance())));
    TestAggregate aggregate = testSubject.load(identifier);
    aggregate.apply(new StubDomainEvent());
    aggregate.apply(new StubDomainEvent());

    CurrentUnitOfWork.commit();

    InOrder inOrder = Mockito.inOrder(decorator1.lastSpy, decorator2.lastSpy);
    inOrder.verify(decorator1.lastSpy).next();
    inOrder.verify(decorator2.lastSpy).next();

    inOrder.verify(decorator1.lastSpy).next();
    inOrder.verify(decorator2.lastSpy).next();
  }