You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ma...@apache.org on 2018/05/17 07:52:25 UTC
[1/4] james-project git commit: JAMES-2393 Introduce dedicated
modules for event sourcing
Repository: james-project
Updated Branches:
refs/heads/master c2b85a004 -> 189490a4e
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java
deleted file mode 100644
index 22a2788..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.Set;
-
-public class EventSourcingSystem {
- private final EventBus eventBus;
- private final CommandDispatcher commandDispatcher;
-
- public EventSourcingSystem(Set<CommandDispatcher.CommandHandler<?>> handlers, Set<Subscriber> subscribers, EventStore eventStore) {
- this.eventBus = new EventBus(eventStore, subscribers);
- this.commandDispatcher = new CommandDispatcher(eventBus, handlers);
- }
-
- public void dispatch(CommandDispatcher.Command c) {
- commandDispatcher.dispatch(c);
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventStore.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventStore.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventStore.java
deleted file mode 100644
index 1ba8028..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventStore.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.ImmutableList;
-
-public interface EventStore {
-
- class EventStoreFailedException extends RuntimeException {
-
- }
-
- class History {
- public static History empty() {
- return new History(ImmutableList.of());
- }
-
- public static History of(List<Event> events) {
- return new History(ImmutableList.copyOf(events));
- }
-
- public static History of(Event... events) {
- return of(ImmutableList.copyOf(events));
- }
-
- private final List<Event> events;
-
- private History(List<Event> events) {
- if (hasEventIdDuplicates(events)) {
- throw new EventStoreFailedException();
- }
- this.events = events;
- }
-
- public boolean hasEventIdDuplicates(List<Event> events) {
- Set<EventId> eventIds = events.stream()
- .map(Event::eventId)
- .collect(Guavate.toImmutableSet());
-
- return eventIds.size() != events.size();
- }
-
- public Optional<EventId> getVersion() {
- return events.stream()
- .map(Event::eventId)
- .max(Comparator.naturalOrder());
- }
-
- public List<Event> getEvents() {
- return events;
- }
-
- public EventId getNextEventId() {
- return getVersion()
- .map(EventId::next)
- .orElse(EventId.first());
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof History) {
- History history = (History) o;
-
- return Objects.equals(this.events, history.events);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(events);
- }
- }
-
- default void append(Event event) {
- appendAll(ImmutableList.of(event));
- }
-
- default void appendAll(Event... events) {
- appendAll(ImmutableList.copyOf(events));
- }
-
- /**
- * This method should check that no input event has an id already stored and throw otherwise
- * It should also check that all events belong to the same aggregate
- */
- void appendAll(List<Event> events);
-
- History getEventsOfAggregate(AggregateId aggregateId);
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Subscriber.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Subscriber.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Subscriber.java
deleted file mode 100644
index 42a804d..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Subscriber.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-public interface Subscriber {
- void handle(Event event);
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/aggregates/UserQuotaThresholds.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/aggregates/UserQuotaThresholds.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/aggregates/UserQuotaThresholds.java
index 8290baf..ae67d30 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/aggregates/UserQuotaThresholds.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/aggregates/UserQuotaThresholds.java
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
import org.apache.james.core.User;
import org.apache.james.eventsourcing.AggregateId;
-import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.eventsourcing.eventstore.History;
import org.apache.james.mailbox.model.Quota;
import org.apache.james.mailbox.quota.QuotaCount;
import org.apache.james.mailbox.quota.QuotaSize;
@@ -82,15 +82,15 @@ public class UserQuotaThresholds {
}
}
- public static UserQuotaThresholds fromEvents(Id aggregateId, EventStore.History history) {
+ public static UserQuotaThresholds fromEvents(Id aggregateId, History history) {
return new UserQuotaThresholds(aggregateId, history);
}
private final Id aggregateId;
- private final EventStore.History history;
+ private final History history;
private final List<QuotaThresholdChangedEvent> events;
- private UserQuotaThresholds(Id aggregateId, EventStore.History history) {
+ private UserQuotaThresholds(Id aggregateId, History history) {
this.aggregateId = aggregateId;
this.history = history;
this.events = history.getEvents().stream()
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossing.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossing.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossing.java
index 0de0023..1128c0b 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossing.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossing.java
@@ -23,12 +23,12 @@ import java.time.Instant;
import java.util.Objects;
import org.apache.james.core.User;
-import org.apache.james.eventsourcing.CommandDispatcher;
+import org.apache.james.eventsourcing.Command;
import org.apache.james.mailbox.model.Quota;
import org.apache.james.mailbox.quota.QuotaCount;
import org.apache.james.mailbox.quota.QuotaSize;
-public class DetectThresholdCrossing implements CommandDispatcher.Command {
+public class DetectThresholdCrossing implements Command {
private final User user;
private final Quota<QuotaCount> countQuota;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossingHandler.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossingHandler.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossingHandler.java
index 39b2013..bbf480e 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossingHandler.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/commands/DetectThresholdCrossingHandler.java
@@ -23,13 +23,14 @@ import java.util.List;
import javax.inject.Inject;
-import org.apache.james.eventsourcing.CommandDispatcher;
+import org.apache.james.eventsourcing.CommandHandler;
import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.eventsourcing.eventstore.EventStore;
+import org.apache.james.eventsourcing.eventstore.History;
import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
import org.apache.james.mailbox.quota.mailing.aggregates.UserQuotaThresholds;
-public class DetectThresholdCrossingHandler implements CommandDispatcher.CommandHandler<DetectThresholdCrossing> {
+public class DetectThresholdCrossingHandler implements CommandHandler<DetectThresholdCrossing> {
private final EventStore eventStore;
private final QuotaMailingListenerConfiguration quotaMailingListenerConfiguration;
@@ -48,7 +49,7 @@ public class DetectThresholdCrossingHandler implements CommandDispatcher.Command
private UserQuotaThresholds loadAggregate(DetectThresholdCrossing command) {
UserQuotaThresholds.Id aggregateId = UserQuotaThresholds.Id.from(command.getUser());
- EventStore.History history = eventStore.getEventsOfAggregate(aggregateId);
+ History history = eventStore.getEventsOfAggregate(aggregateId);
return UserQuotaThresholds.fromEvents(aggregateId, history);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java
deleted file mode 100644
index 85fccd1..0000000
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.google.common.collect.ImmutableList;
-
-public class DataCollectorSubscriber implements Subscriber {
-
- private final List<String> data;
-
- public DataCollectorSubscriber() {
- data = new ArrayList<>();
- }
-
- @Override
- public void handle(Event event) {
- if (event instanceof TestEvent) {
- data.add(((TestEvent) event).getData());
- }
- }
-
-
- public List<String> getData() {
- return ImmutableList.copyOf(data);
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventIdTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventIdTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventIdTest.java
deleted file mode 100644
index ffdc5f2..0000000
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventIdTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-public class EventIdTest {
-
- @Test
- public void shouldMatchBeanContract() {
- EqualsVerifier.forClass(EventStore.History.class)
- .allFieldsShouldBeUsed()
- .verify();
- }
-
- @Test
- public void firstShouldReturnAConstant() {
- assertThat(EventId.first())
- .isEqualTo(EventId.first());
- }
-
- @Test
- public void previousShouldReturnEmptyWhenBeforeFirst() {
- assertThat(EventId.first().previous())
- .isEmpty();
- }
-
- @Test
- public void compareToShouldReturnNegativeWhenComparedToNext() {
- assertThat(EventId.first())
- .isLessThan(EventId.first().next());
- }
-
- @Test
- public void compareToShouldReturnNegativeWhenComparedToPrevious() {
- assertThat(EventId.first().next())
- .isGreaterThan(EventId.first());
- }
-
- @Test
- public void nextShouldAlwaysHaveTheSameIncrement() {
- assertThat(EventId.first().next())
- .isEqualTo(EventId.first().next());
- }
-
- @Test
- public void previousShouldRevertNext() {
- assertThat(EventId.first().next().previous())
- .contains(EventId.first());
- }
-
- @Test
- public void compareToShouldReturnNegativeWhenComparedToNextWithPreviousCall() {
- assertThat(EventId.first().next().previous().get())
- .isLessThan(EventId.first().next());
- }
-
- @Test
- public void compareToShouldReturnNegativeWhenComparedToPreviousWithPreviousCall() {
- assertThat(EventId.first().next())
- .isGreaterThan(EventId.first().next().previous().get());
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
deleted file mode 100644
index 19c3925..0000000
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyListOf;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public interface EventSourcingSystemTest {
-
- String PAYLOAD_1 = "payload1";
- String PAYLOAD_2 = "payload2";
- TestAggregateId AGGREGATE_ID = TestAggregateId.testId(42);
-
- class MyCommand implements CommandDispatcher.Command {
- private final String payload;
-
- public MyCommand(String payload) {
- this.payload = payload;
- }
-
- public String getPayload() {
- return payload;
- }
- }
-
- @Test
- default void dispatchShouldApplyCommandHandlerThenCallSubscribers(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(simpleDispatcher(eventStore)),
- ImmutableSet.of(subscriber),
- eventStore);
-
- eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
-
- assertThat(subscriber.getData()).containsExactly(PAYLOAD_1);
- }
-
- @Test
- default void throwingSubscribersShouldNotAbortSubscriberChain(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(simpleDispatcher(eventStore)),
- ImmutableSet.of(
- events -> {
- throw new RuntimeException();
- },
- subscriber),
- eventStore);
-
- eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
-
- assertThat(subscriber.getData()).containsExactly(PAYLOAD_1);
- }
-
- @Test
- default void throwingStoreShouldNotLeadToPusblishing() {
- EventStore eventStore = mock(EventStore.class);
- doThrow(new RuntimeException()).when(eventStore).appendAll(anyListOf(Event.class));
- when(eventStore.getEventsOfAggregate(any())).thenReturn(EventStore.History.empty());
-
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(simpleDispatcher(eventStore)),
- ImmutableSet.of(
- events -> {
- throw new RuntimeException();
- },
- subscriber),
- eventStore);
-
- assertThatThrownBy(() -> eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1)))
- .isInstanceOf(RuntimeException.class);
-
- assertThat(subscriber.getData()).isEmpty();
- }
-
- @Test
- default void dispatchShouldApplyCommandHandlerThenStoreGeneratedEvents(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(simpleDispatcher(eventStore)),
- ImmutableSet.of(subscriber),
- eventStore);
-
- eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
-
- TestEvent expectedEvent = new TestEvent(EventId.first(), AGGREGATE_ID, PAYLOAD_1);
- assertThat(eventStore.getEventsOfAggregate(AGGREGATE_ID).getEvents())
- .containsOnly(expectedEvent);
- }
-
- @Test
- default void dispatchShouldCallSubscriberForSubsequentCommands(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(simpleDispatcher(eventStore)),
- ImmutableSet.of(subscriber),
- eventStore);
-
- eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
- eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_2));
-
- assertThat(subscriber.getData()).containsExactly(PAYLOAD_1, PAYLOAD_2);
- }
-
- @Test
- default void dispatchShouldStoreEventsForSubsequentCommands(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(simpleDispatcher(eventStore)),
- ImmutableSet.of(subscriber),
- eventStore);
-
- eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
- eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_2));
-
- TestEvent expectedEvent1 = new TestEvent(EventId.first(), AGGREGATE_ID, PAYLOAD_1);
- TestEvent expectedEvent2 = new TestEvent(expectedEvent1.eventId().next(), AGGREGATE_ID, PAYLOAD_2);
- assertThat(eventStore.getEventsOfAggregate(AGGREGATE_ID).getEvents())
- .containsOnly(expectedEvent1, expectedEvent2);
- }
-
- @Test
- default void dispatcherShouldBeAbleToReturnSeveralEvents(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(wordCuttingDispatcher(eventStore)),
- ImmutableSet.of(subscriber),
- eventStore);
-
- eventSourcingSystem.dispatch(new MyCommand("This is a test"));
-
- assertThat(subscriber.getData()).containsExactly("This", "is", "a", "test");
- }
-
- @Test
- default void unknownCommandsShouldBeIgnored(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
- EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
- ImmutableSet.of(wordCuttingDispatcher(eventStore)),
- ImmutableSet.of(subscriber),
- eventStore);
-
- assertThatThrownBy(() -> eventSourcingSystem.dispatch(new CommandDispatcher.Command() {}))
- .isInstanceOf(CommandDispatcher.UnknownCommandException.class);
- }
-
- @Test
- default void constructorShouldThrowWhenSeveralHandlersForTheSameCommand(EventStore eventStore) {
- DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
-
- assertThatThrownBy(() ->
- new EventSourcingSystem(
- ImmutableSet.of(wordCuttingDispatcher(eventStore),
- simpleDispatcher(eventStore)),
- ImmutableSet.of(subscriber),
- eventStore))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- default CommandDispatcher.CommandHandler<MyCommand> simpleDispatcher(EventStore eventStore) {
- return new CommandDispatcher.CommandHandler<MyCommand>() {
- @Override
- public Class<MyCommand> handledClass() {
- return MyCommand.class;
- }
-
- @Override
- public List<? extends Event> handle(MyCommand myCommand) {
- EventStore.History history = eventStore.getEventsOfAggregate(AGGREGATE_ID);
-
- return ImmutableList.of(new TestEvent(
- history.getNextEventId(),
- AGGREGATE_ID,
- myCommand.getPayload()));
- }
- };
- }
-
- default CommandDispatcher.CommandHandler<MyCommand> wordCuttingDispatcher(EventStore eventStore) {
- return new CommandDispatcher.CommandHandler<MyCommand>() {
- @Override
- public Class<MyCommand> handledClass() {
- return MyCommand.class;
- }
-
- @Override
- public List<? extends Event> handle(MyCommand myCommand) {
- EventStore.History history = eventStore.getEventsOfAggregate(AGGREGATE_ID);
-
- EventIdIncrementer eventIdIncrementer = new EventIdIncrementer(history.getNextEventId());
-
- return Splitter.on(" ")
- .splitToList(myCommand.getPayload())
- .stream()
- .map(word -> new TestEvent(
- eventIdIncrementer.next(),
- AGGREGATE_ID,
- word))
- .collect(Guavate.toImmutableList());
- }
- };
- }
-
- class EventIdIncrementer {
- private EventId currentEventId;
-
- public EventIdIncrementer(EventId base) {
- this.currentEventId = base;
- }
-
- public EventId next() {
- currentEventId = currentEventId.next();
- return currentEventId;
- }
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java
deleted file mode 100644
index aad8daa..0000000
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.apache.james.eventsourcing;
-
-import static org.apache.james.eventsourcing.TestAggregateId.testId;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableList;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-public interface EventStoreTest {
-
- TestAggregateId AGGREGATE_1 = testId(1);
- TestAggregateId AGGREGATE_2 = testId(2);
-
- @Test
- default void historyShouldMatchBeanContract() {
- EqualsVerifier.forClass(EventStore.History.class)
- .allFieldsShouldBeUsed()
- .verify();
- }
-
- @Test
- default void getEventsOfAggregateShouldThrowOnNullAggregateId(EventStore testee) {
- assertThatThrownBy(() -> testee.getEventsOfAggregate(null))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- default void appendShouldThrowWhenEventFromSeveralAggregates(EventStore testee) {
- TestEvent event1 = new TestEvent(EventId.first(), AGGREGATE_1, "first");
- TestEvent event2 = new TestEvent(event1.eventId().next(), AGGREGATE_2, "second");
- assertThatThrownBy(() -> testee.appendAll(event1, event2)).isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- default void appendShouldDoNothingOnEmptyEventList(EventStore testee) {
- assertThatCode(testee::appendAll).doesNotThrowAnyException();
- }
-
- @Test
- default void appendShouldThrowWhenTryingToRewriteHistory(EventStore testee) {
- TestEvent event1 = new TestEvent(EventId.first(), AGGREGATE_1, "first");
- testee.append(event1);
- TestEvent event2 = new TestEvent(EventId.first(), AGGREGATE_1, "second");
- assertThatThrownBy(() -> testee.append(event2)).isInstanceOf(EventStore.EventStoreFailedException.class);
- }
-
- @Test
- default void getEventsOfAggregateShouldReturnEmptyHistoryWhenUnknown(EventStore testee) {
- assertThat(testee.getEventsOfAggregate(AGGREGATE_1)).isEqualTo(EventStore.History.empty());
- }
-
- @Test
- default void getEventsOfAggregateShouldReturnAppendedEvent(EventStore testee) {
- TestEvent event = new TestEvent(EventId.first(), AGGREGATE_1, "first");
- testee.append(event);
- assertThat(testee.getEventsOfAggregate(AGGREGATE_1))
- .isEqualTo(EventStore.History.of(ImmutableList.of(event)));
- }
-
- @Test
- default void getEventsOfAggregateShouldReturnAppendedEvents(EventStore testee) {
- TestEvent event1 = new TestEvent(EventId.first(), AGGREGATE_1, "first");
- TestEvent event2 = new TestEvent(event1.eventId().next(), AGGREGATE_1, "second");
- testee.append(event1);
- testee.append(event2);
- assertThat(testee.getEventsOfAggregate(AGGREGATE_1))
- .isEqualTo(EventStore.History.of(ImmutableList.of(event1, event2)));
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/HistoryTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/HistoryTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/HistoryTest.java
deleted file mode 100644
index 9419087..0000000
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/HistoryTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-public class HistoryTest {
-
- @Test
- public void shouldMatchBeanContract() {
- EqualsVerifier.forClass(EventStore.History.class)
- .verify();
- }
-
- @Test
- public void emptyShouldGenerateAnEmptyHistory() {
- assertThat(EventStore.History.empty())
- .isEqualTo(EventStore.History.of());
- }
-
- @Test
- public void getVersionShouldReturnEmptyWhenEmpty() {
- assertThat(EventStore.History.empty()
- .getVersion())
- .isEmpty();
- }
-
- @Test
- public void getVersionShouldReturnSingleEventIdWhenSingleEvent() {
- assertThat(EventStore.History
- .of(new TestEvent(EventId.first(),
- TestAggregateId.testId(42),
- "any"))
- .getVersion())
- .contains(EventId.first());
- }
-
- @Test
- public void getVersionShouldReturnHighestEventId() {
- TestEvent event1 = new TestEvent(EventId.first(),
- TestAggregateId.testId(42),
- "any");
- TestEvent event2 = new TestEvent(event1.eventId().next(),
- TestAggregateId.testId(42),
- "any");
-
- assertThat(EventStore.History.of(event1, event2)
- .getVersion())
- .contains(event2.eventId());
- }
-
- @Test
- public void duplicateHistoryShouldThrow() {
- TestEvent event1 = new TestEvent(EventId.first(),
- TestAggregateId.testId(42),
- "any");
- TestEvent event2 = new TestEvent(EventId.first(),
- TestAggregateId.testId(42),
- "any");
-
- assertThatThrownBy(() -> EventStore.History.of(event1, event2))
- .isInstanceOf(EventStore.EventStoreFailedException.class);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
deleted file mode 100644
index b3ae78c..0000000
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.Objects;
-
-import com.google.common.base.MoreObjects;
-
-public class TestAggregateId implements AggregateId {
-
- public static TestAggregateId testId(int id) {
- return new TestAggregateId(id);
- }
-
- private final int id;
-
- private TestAggregateId(int id) {
- this.id = id;
- }
-
- @Override
- public String asAggregateKey() {
- return "TestAggregateId-" + id;
- }
-
- public int getId() {
- return id;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof TestAggregateId) {
- TestAggregateId that = (TestAggregateId) o;
-
- return Objects.equals(this.id, that.id);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("id", id)
- .toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestEvent.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestEvent.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestEvent.java
deleted file mode 100644
index c46f804..0000000
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestEvent.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.Comparator;
-import java.util.Objects;
-
-import com.google.common.base.MoreObjects;
-
-public class TestEvent implements Event {
- private final EventId id;
- private final TestAggregateId aggregateId;
- private final String data;
-
- public TestEvent(EventId id, TestAggregateId aggregateId, String data) {
- this.id = id;
- this.aggregateId = aggregateId;
- this.data = data;
- }
-
- @Override
- public EventId eventId() {
- return id;
- }
-
- @Override
- public TestAggregateId getAggregateId() {
- return aggregateId;
- }
-
- public String getData() {
- return data;
- }
-
- @Override
- public int compareTo(Event o) {
- return Comparator.<EventId>naturalOrder().compare(id, o.eventId());
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof TestEvent) {
- TestEvent testEvent = (TestEvent) o;
-
- return Objects.equals(this.id, testEvent.id)
- && Objects.equals(this.aggregateId, testEvent.aggregateId)
- && Objects.equals(this.data, testEvent.data);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, aggregateId, data);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("id", id)
- .add("aggregateId", aggregateId)
- .add("data", data)
- .toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
index fe57929..166d86c 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
@@ -28,7 +28,7 @@ import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._75;
import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.mailetContext;
import static org.assertj.core.api.Assertions.assertThat;
-import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.eventsourcing.eventstore.EventStore;
import org.apache.james.mailbox.MailboxListener.QuotaUsageUpdatedEvent;
import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Counts;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
index bb1dce8..0b279dd 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
@@ -20,7 +20,7 @@
package org.apache.james.mailbox.quota.mailing.listeners;
import org.apache.james.eventsourcing.EventSourcingSystem;
-import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.eventsourcing.eventstore.EventStore;
import org.apache.james.filesystem.api.FileSystem;
import org.apache.james.mailbox.Event;
import org.apache.james.mailbox.exception.MailboxException;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
index 604d891..362246f 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
@@ -37,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.concurrent.TimeUnit;
-import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.eventsourcing.eventstore.EventStore;
import org.apache.james.mailbox.MailboxListener.QuotaUsageUpdatedEvent;
import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Counts;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 4a41df0..16beb29 100644
--- a/pom.xml
+++ b/pom.xml
@@ -526,6 +526,7 @@
<modules>
<module>backends-common</module>
<module>core</module>
+ <module>event-sourcing</module>
<module>javax-mail-extension</module>
<module>mailbox</module>
<module>mailet</module>
@@ -1001,6 +1002,66 @@
<artifactId>blob-cassandra</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-cassandra</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-cassandra</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-memory</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>james-server-cassandra-guice</artifactId>
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[4/4] james-project git commit: JAMES-2393 Introduce dedicated
modules for event sourcing
Posted by ma...@apache.org.
JAMES-2393 Introduce dedicated modules for event sourcing
This intend to ease future usage, external usage as well as allow a clear view.
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/189490a4
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/189490a4
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/189490a4
Branch: refs/heads/master
Commit: 189490a4eaabaa9876a0c73b3f5f035ec6565c65
Parents: c2b85a0
Author: benwa <bt...@linagora.com>
Authored: Thu May 10 11:29:21 2018 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu May 17 09:50:00 2018 +0200
----------------------------------------------------------------------
event-sourcing/event-sourcing-core/pom.xml | 90 +++++++
.../james/eventsourcing/CommandDispatcher.java | 110 ++++++++
.../james/eventsourcing/CommandHandler.java | 29 +++
.../apache/james/eventsourcing/EventBus.java | 63 +++++
.../eventsourcing/EventSourcingSystem.java | 37 +++
.../apache/james/eventsourcing/Subscriber.java | 24 ++
.../eventsourcing/DataCollectorSubscriber.java | 46 ++++
.../eventsourcing/EventSourcingSystemTest.java | 252 +++++++++++++++++++
event-sourcing/event-sourcing-pojo/pom.xml | 67 +++++
.../apache/james/eventsourcing/AggregateId.java | 24 ++
.../org/apache/james/eventsourcing/Command.java | 23 ++
.../org/apache/james/eventsourcing/Event.java | 43 ++++
.../org/apache/james/eventsourcing/EventId.java | 86 +++++++
.../apache/james/eventsourcing/EventIdTest.java | 85 +++++++
.../james/eventsourcing/TestAggregateId.java | 68 +++++
.../apache/james/eventsourcing/TestEvent.java | 82 ++++++
event-sourcing/event-store-api/pom.xml | 77 ++++++
.../eventsourcing/eventstore/EventStore.java | 47 ++++
.../eventstore/EventStoreFailedException.java | 23 ++
.../james/eventsourcing/eventstore/History.java | 94 +++++++
.../eventstore/EventStoreTest.java | 88 +++++++
.../eventsourcing/eventstore/HistoryTest.java | 91 +++++++
event-sourcing/event-store-cassandra/pom.xml | 131 ++++++++++
.../cassandra/CassandraEventStore.java | 64 +++++
.../cassandra/CassandraEventStoreModule.java | 62 +++++
.../cassandra/CassandraEventStoreTable.java | 27 ++
.../eventstore/cassandra/EventStoreDao.java | 122 +++++++++
.../cassandra/JsonEventSerializer.java | 98 ++++++++
.../eventstore/cassandra/dto/EventDTO.java | 26 ++
.../cassandra/dto/EventDTOModule.java | 32 +++
.../CassandraEventSourcingSystemTest.java | 28 +++
.../cassandra/CassandraEventStoreExtension.java | 30 +++
.../cassandra/CassandraEventStoreTest.java | 28 +++
.../CassandraGenericEventStoreExtension.java | 87 +++++++
.../cassandra/JsonEventSerializerTest.java | 102 ++++++++
.../eventstore/cassandra/dto/OtherEvent.java | 50 ++++
.../cassandra/dto/OtherTestEventDTO.java | 72 ++++++
.../cassandra/dto/OtherTestEventDTOModule.java | 55 ++++
.../eventstore/cassandra/dto/TestEventDTO.java | 73 ++++++
.../cassandra/dto/TestEventDTOModule.java | 56 +++++
event-sourcing/event-store-memory/pom.xml | 86 +++++++
.../eventstore/memory/InMemoryEventStore.java | 99 ++++++++
.../memory/InMemoryEventSourcingSystemTest.java | 28 +++
.../memory/InMemoryEventStoreExtension.java | 39 +++
.../memory/InMemoryEventStoreTest.java | 28 +++
event-sourcing/pom.xml | 44 ++++
mailbox/plugin/quota-mailing-cassandra/pom.xml | 21 ++
.../cassandra/CassandraEventStore.java | 62 -----
.../cassandra/CassandraEventStoreModule.java | 62 -----
.../cassandra/CassandraEventStoreTable.java | 27 --
.../eventsourcing/cassandra/EventStoreDao.java | 122 ---------
.../cassandra/JsonEventSerializer.java | 98 --------
.../eventsourcing/cassandra/dto/EventDTO.java | 26 --
.../cassandra/dto/EventDTOModule.java | 32 ---
.../dto/QuotaThresholdChangedEventDTO.java | 2 +-
.../QuotaThresholdChangedEventDTOModule.java | 4 +-
.../CassandraEventSourcingSystemTest.java | 28 ---
.../cassandra/CassandraEventStoreExtension.java | 86 -------
.../cassandra/CassandraEventStoreTest.java | 28 ---
.../cassandra/JsonEventSerializerTest.java | 102 --------
.../eventsourcing/cassandra/dto/OtherEvent.java | 50 ----
.../cassandra/dto/OtherTestEventDTO.java | 72 ------
.../cassandra/dto/OtherTestEventDTOModule.java | 55 ----
.../cassandra/dto/TestEventDTO.java | 73 ------
.../cassandra/dto/TestEventDTOModule.java | 56 -----
.../mailbox/quota/cassandra/dto/DTOTest.java | 30 +--
.../listeners/CassandraEventStoreExtension.java | 32 +++
...draQuotaMailingListenersIntegrationTest.java | 1 -
mailbox/plugin/quota-mailing-memory/pom.xml | 21 ++
.../james/eventsource/InMemoryEventStore.java | 97 -------
.../InMemoryEventSourcingSystemTest.java | 27 --
.../InMemoryEventStoreExtension.java | 39 ---
.../eventsourcing/InMemoryEventStoreTest.java | 27 --
...oryQuotaMailingListenersIntegrationTest.java | 2 +-
...yQuotaThresholdConfigurationChangesTest.java | 2 +-
mailbox/plugin/quota-mailing/pom.xml | 14 ++
.../apache/james/eventsourcing/AggregateId.java | 24 --
.../james/eventsourcing/CommandDispatcher.java | 117 ---------
.../org/apache/james/eventsourcing/Event.java | 43 ----
.../apache/james/eventsourcing/EventBus.java | 61 -----
.../org/apache/james/eventsourcing/EventId.java | 86 -------
.../eventsourcing/EventSourcingSystem.java | 36 ---
.../apache/james/eventsourcing/EventStore.java | 114 ---------
.../apache/james/eventsourcing/Subscriber.java | 24 --
.../mailing/aggregates/UserQuotaThresholds.java | 8 +-
.../commands/DetectThresholdCrossing.java | 4 +-
.../DetectThresholdCrossingHandler.java | 9 +-
.../eventsourcing/DataCollectorSubscriber.java | 46 ----
.../apache/james/eventsourcing/EventIdTest.java | 85 -------
.../eventsourcing/EventSourcingSystemTest.java | 250 ------------------
.../james/eventsourcing/EventStoreTest.java | 75 ------
.../apache/james/eventsourcing/HistoryTest.java | 87 -------
.../james/eventsourcing/TestAggregateId.java | 68 -----
.../apache/james/eventsourcing/TestEvent.java | 82 ------
.../QuotaThresholdConfigurationChangesTest.java | 2 +-
.../QuotaThresholdListenersTestSystem.java | 2 +-
.../QuotaThresholdMailingIntegrationTest.java | 2 +-
pom.xml | 61 +++++
98 files changed, 3199 insertions(+), 2401 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/pom.xml
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/pom.xml b/event-sourcing/event-sourcing-core/pom.xml
new file mode 100644
index 0000000..7b7c6e1
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.james</groupId>
+ <artifactId>event-sourcing</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>event-sourcing-core</artifactId>
+
+ <name>Apache James :: Event sourcing :: core</name>
+ <description>James Event Sourcing system</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.github.steveash.guavate</groupId>
+ <artifactId>guavate</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>nl.jqno.equalsverifier</groupId>
+ <artifactId>equalsverifier</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-launcher</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java
new file mode 100644
index 0000000..15d128c
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java
@@ -0,0 +1,110 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
+import java.util.stream.IntStream;
+
+import javax.inject.Inject;
+
+import org.apache.james.eventsourcing.eventstore.EventStoreFailedException;
+
+import com.github.steveash.guavate.Guavate;
+
+public class CommandDispatcher {
+
+ private static final int MAX_RETRY = 10;
+
+ public class UnknownCommandException extends RuntimeException {
+ private final Command command;
+
+ public UnknownCommandException(Command command) {
+ super(String.format("Unknown command %s", command));
+ this.command = command;
+ }
+
+ public Command getCommand() {
+ return command;
+ }
+ }
+
+ public class TooManyRetries extends RuntimeException {
+ private final Command command;
+ private final int retries;
+
+
+ public TooManyRetries(Command command, int retries) {
+ super(String.format("Too much retries for command %s. Store failure after %d retries", command, retries));
+ this.command = command;
+ this.retries = retries;
+ }
+
+
+ public Command getCommand() {
+ return command;
+ }
+
+ public int getRetries() {
+ return retries;
+ }
+ }
+
+ private final EventBus eventBus;
+ @SuppressWarnings("rawtypes")
+ private final Map<Class, CommandHandler> handlers;
+
+ @Inject
+ public CommandDispatcher(EventBus eventBus, Set<CommandHandler<?>> handlers) {
+ this.eventBus = eventBus;
+ this.handlers = handlers.stream()
+ .collect(Guavate.toImmutableMap(CommandHandler::handledClass, handler -> handler));
+ }
+
+ public void dispatch(Command c) {
+ trySeveralTimes(() -> tryDispatch(c))
+ .orElseThrow(() -> new TooManyRetries(c, MAX_RETRY));
+ }
+
+ public Optional<Integer> trySeveralTimes(Supplier<Boolean> singleTry) {
+ return IntStream.range(0, MAX_RETRY)
+ .boxed()
+ .filter(any -> singleTry.get())
+ .findFirst();
+ }
+
+ @SuppressWarnings("unchecked")
+ private boolean tryDispatch(Command c) {
+ try {
+ List<Event> events =
+ Optional.ofNullable(handlers.get(c.getClass()))
+ .map(f -> f.handle(c))
+ .orElseThrow(() -> new UnknownCommandException(c));
+
+ eventBus.publish(events);
+ return true;
+ } catch (EventStoreFailedException e) {
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandHandler.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandHandler.java b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandHandler.java
new file mode 100644
index 0000000..6b8aacf
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/CommandHandler.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.List;
+
+public interface CommandHandler<C> {
+
+ Class<C> handledClass();
+
+ List<? extends Event> handle(C c);
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventBus.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventBus.java b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventBus.java
new file mode 100644
index 0000000..289433e
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventBus.java
@@ -0,0 +1,63 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.eventsourcing.eventstore.EventStore;
+import org.apache.james.eventsourcing.eventstore.EventStoreFailedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSet;
+
+public class EventBus {
+
+ public static final Logger LOGGER = LoggerFactory.getLogger(EventBus.class);
+ private final EventStore eventStore;
+ private final Set<Subscriber> subscribers;
+
+ @Inject
+ public EventBus(EventStore eventStore, Set<Subscriber> subscribers) {
+ this.eventStore = eventStore;
+ this.subscribers = ImmutableSet.copyOf(subscribers);
+ }
+
+ public void publish(List<Event> events) throws EventStoreFailedException {
+ eventStore.appendAll(events);
+ events.stream()
+ .flatMap(event -> subscribers.stream().map(subscriber -> Pair.of(event, subscriber)))
+ .forEach(this::handle);
+ }
+
+ public void handle(Pair<Event, Subscriber> pair) {
+ Subscriber subscriber = pair.getRight();
+ Event event = pair.getLeft();
+ try {
+ subscriber.handle(event);
+ } catch (Exception e) {
+ LOGGER.error("Error while calling {} for {}", subscriber, event, e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java
new file mode 100644
index 0000000..e077fe6
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/EventSourcingSystem.java
@@ -0,0 +1,37 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.Set;
+
+import org.apache.james.eventsourcing.eventstore.EventStore;
+
+public class EventSourcingSystem {
+ private final CommandDispatcher commandDispatcher;
+
+ public EventSourcingSystem(Set<CommandHandler<?>> handlers, Set<Subscriber> subscribers, EventStore eventStore) {
+ EventBus eventBus = new EventBus(eventStore, subscribers);
+ this.commandDispatcher = new CommandDispatcher(eventBus, handlers);
+ }
+
+ public void dispatch(Command c) {
+ commandDispatcher.dispatch(c);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/Subscriber.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/Subscriber.java b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/Subscriber.java
new file mode 100644
index 0000000..42a804d
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/src/main/java/org/apache/james/eventsourcing/Subscriber.java
@@ -0,0 +1,24 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+public interface Subscriber {
+ void handle(Event event);
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java b/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java
new file mode 100644
index 0000000..85fccd1
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/DataCollectorSubscriber.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+
+public class DataCollectorSubscriber implements Subscriber {
+
+ private final List<String> data;
+
+ public DataCollectorSubscriber() {
+ data = new ArrayList<>();
+ }
+
+ @Override
+ public void handle(Event event) {
+ if (event instanceof TestEvent) {
+ data.add(((TestEvent) event).getData());
+ }
+ }
+
+
+ public List<String> getData() {
+ return ImmutableList.copyOf(data);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java b/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
new file mode 100644
index 0000000..02c9eec
--- /dev/null
+++ b/event-sourcing/event-sourcing-core/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
@@ -0,0 +1,252 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+import org.apache.james.eventsourcing.eventstore.EventStore;
+import org.apache.james.eventsourcing.eventstore.History;
+import org.junit.jupiter.api.Test;
+
+import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public interface EventSourcingSystemTest {
+
+ String PAYLOAD_1 = "payload1";
+ String PAYLOAD_2 = "payload2";
+ TestAggregateId AGGREGATE_ID = TestAggregateId.testId(42);
+
+ class MyCommand implements Command {
+ private final String payload;
+
+ public MyCommand(String payload) {
+ this.payload = payload;
+ }
+
+ public String getPayload() {
+ return payload;
+ }
+ }
+
+ @Test
+ default void dispatchShouldApplyCommandHandlerThenCallSubscribers(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(simpleDispatcher(eventStore)),
+ ImmutableSet.of(subscriber),
+ eventStore);
+
+ eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
+
+ assertThat(subscriber.getData()).containsExactly(PAYLOAD_1);
+ }
+
+ @Test
+ default void throwingSubscribersShouldNotAbortSubscriberChain(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(simpleDispatcher(eventStore)),
+ ImmutableSet.of(
+ events -> {
+ throw new RuntimeException();
+ },
+ subscriber),
+ eventStore);
+
+ eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
+
+ assertThat(subscriber.getData()).containsExactly(PAYLOAD_1);
+ }
+
+ @Test
+ default void throwingStoreShouldNotLeadToPusblishing() {
+ EventStore eventStore = mock(EventStore.class);
+ doThrow(new RuntimeException()).when(eventStore).appendAll(anyListOf(Event.class));
+ when(eventStore.getEventsOfAggregate(any())).thenReturn(History.empty());
+
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(simpleDispatcher(eventStore)),
+ ImmutableSet.of(
+ events -> {
+ throw new RuntimeException();
+ },
+ subscriber),
+ eventStore);
+
+ assertThatThrownBy(() -> eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1)))
+ .isInstanceOf(RuntimeException.class);
+
+ assertThat(subscriber.getData()).isEmpty();
+ }
+
+ @Test
+ default void dispatchShouldApplyCommandHandlerThenStoreGeneratedEvents(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(simpleDispatcher(eventStore)),
+ ImmutableSet.of(subscriber),
+ eventStore);
+
+ eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
+
+ TestEvent expectedEvent = new TestEvent(EventId.first(), AGGREGATE_ID, PAYLOAD_1);
+ assertThat(eventStore.getEventsOfAggregate(AGGREGATE_ID).getEvents())
+ .containsOnly(expectedEvent);
+ }
+
+ @Test
+ default void dispatchShouldCallSubscriberForSubsequentCommands(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(simpleDispatcher(eventStore)),
+ ImmutableSet.of(subscriber),
+ eventStore);
+
+ eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
+ eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_2));
+
+ assertThat(subscriber.getData()).containsExactly(PAYLOAD_1, PAYLOAD_2);
+ }
+
+ @Test
+ default void dispatchShouldStoreEventsForSubsequentCommands(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(simpleDispatcher(eventStore)),
+ ImmutableSet.of(subscriber),
+ eventStore);
+
+ eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
+ eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_2));
+
+ TestEvent expectedEvent1 = new TestEvent(EventId.first(), AGGREGATE_ID, PAYLOAD_1);
+ TestEvent expectedEvent2 = new TestEvent(expectedEvent1.eventId().next(), AGGREGATE_ID, PAYLOAD_2);
+ assertThat(eventStore.getEventsOfAggregate(AGGREGATE_ID).getEvents())
+ .containsOnly(expectedEvent1, expectedEvent2);
+ }
+
+ @Test
+ default void dispatcherShouldBeAbleToReturnSeveralEvents(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(wordCuttingDispatcher(eventStore)),
+ ImmutableSet.of(subscriber),
+ eventStore);
+
+ eventSourcingSystem.dispatch(new MyCommand("This is a test"));
+
+ assertThat(subscriber.getData()).containsExactly("This", "is", "a", "test");
+ }
+
+ @Test
+ default void unknownCommandsShouldBeIgnored(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+ EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(wordCuttingDispatcher(eventStore)),
+ ImmutableSet.of(subscriber),
+ eventStore);
+
+ assertThatThrownBy(() -> eventSourcingSystem.dispatch(new Command() {}))
+ .isInstanceOf(CommandDispatcher.UnknownCommandException.class);
+ }
+
+ @Test
+ default void constructorShouldThrowWhenSeveralHandlersForTheSameCommand(EventStore eventStore) {
+ DataCollectorSubscriber subscriber = new DataCollectorSubscriber();
+
+ assertThatThrownBy(() ->
+ new EventSourcingSystem(
+ ImmutableSet.of(wordCuttingDispatcher(eventStore),
+ simpleDispatcher(eventStore)),
+ ImmutableSet.of(subscriber),
+ eventStore))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ default CommandHandler<MyCommand> simpleDispatcher(EventStore eventStore) {
+ return new CommandHandler<MyCommand>() {
+ @Override
+ public Class<MyCommand> handledClass() {
+ return MyCommand.class;
+ }
+
+ @Override
+ public List<? extends Event> handle(MyCommand myCommand) {
+ History history = eventStore.getEventsOfAggregate(AGGREGATE_ID);
+
+ return ImmutableList.of(new TestEvent(
+ history.getNextEventId(),
+ AGGREGATE_ID,
+ myCommand.getPayload()));
+ }
+ };
+ }
+
+ default CommandHandler<MyCommand> wordCuttingDispatcher(EventStore eventStore) {
+ return new CommandHandler<MyCommand>() {
+ @Override
+ public Class<MyCommand> handledClass() {
+ return MyCommand.class;
+ }
+
+ @Override
+ public List<? extends Event> handle(MyCommand myCommand) {
+ History history = eventStore.getEventsOfAggregate(AGGREGATE_ID);
+
+ EventIdIncrementer eventIdIncrementer = new EventIdIncrementer(history.getNextEventId());
+
+ return Splitter.on(" ")
+ .splitToList(myCommand.getPayload())
+ .stream()
+ .map(word -> new TestEvent(
+ eventIdIncrementer.next(),
+ AGGREGATE_ID,
+ word))
+ .collect(Guavate.toImmutableList());
+ }
+ };
+ }
+
+ class EventIdIncrementer {
+ private EventId currentEventId;
+
+ public EventIdIncrementer(EventId base) {
+ this.currentEventId = base;
+ }
+
+ public EventId next() {
+ currentEventId = currentEventId.next();
+ return currentEventId;
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/pom.xml
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/pom.xml b/event-sourcing/event-sourcing-pojo/pom.xml
new file mode 100644
index 0000000..c27130f
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.james</groupId>
+ <artifactId>event-sourcing</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>event-sourcing-pojo</artifactId>
+
+ <name>Apache James :: Event sourcing :: pojo</name>
+ <description>James event sourcing types</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.github.steveash.guavate</groupId>
+ <artifactId>guavate</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>nl.jqno.equalsverifier</groupId>
+ <artifactId>equalsverifier</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-launcher</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/AggregateId.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/AggregateId.java b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/AggregateId.java
new file mode 100644
index 0000000..18c6224
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/AggregateId.java
@@ -0,0 +1,24 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+public interface AggregateId {
+ String asAggregateKey();
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Command.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Command.java b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Command.java
new file mode 100644
index 0000000..dad8332
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Command.java
@@ -0,0 +1,23 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+public interface Command {
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Event.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Event.java b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Event.java
new file mode 100644
index 0000000..2b31374
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/Event.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.List;
+
+public interface Event extends Comparable<Event> {
+
+ static boolean belongsToSameAggregate(List<? extends Event> events) {
+ return events.stream()
+ .map(Event::getAggregateId)
+ .distinct()
+ .limit(2)
+ .count() == 1;
+ }
+
+ EventId eventId();
+
+ AggregateId getAggregateId();
+
+ @Override
+ default int compareTo(Event o) {
+ return eventId().compareTo(o.eventId());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/EventId.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/EventId.java b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/EventId.java
new file mode 100644
index 0000000..cb5bd1e
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/src/main/java/org/apache/james/eventsourcing/EventId.java
@@ -0,0 +1,86 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+public class EventId implements Comparable<EventId> {
+
+ public static EventId fromSerialized(int value) {
+ return new EventId(value);
+ }
+
+ public static EventId first() {
+ return new EventId(0);
+ }
+
+ private final int value;
+
+ private EventId(int value) {
+ Preconditions.checkArgument(value >= 0, "EventId can not be negative");
+ this.value = value;
+ }
+
+ public EventId next() {
+ return new EventId(value + 1);
+ }
+
+ public Optional<EventId> previous() {
+ if (value > 0) {
+ return Optional.of(new EventId(value - 1));
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public int compareTo(EventId o) {
+ return Long.compare(value, o.value);
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof EventId) {
+ EventId eventId = (EventId) o;
+
+ return Objects.equals(this.value, eventId.value);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(value);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("value", value)
+ .toString();
+ }
+
+ public int serialize() {
+ return value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/EventIdTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/EventIdTest.java b/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/EventIdTest.java
new file mode 100644
index 0000000..1b46fbf
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/EventIdTest.java
@@ -0,0 +1,85 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class EventIdTest {
+
+ @Test
+ void shouldMatchBeanContract() {
+ EqualsVerifier.forClass(EventId.class)
+ .allFieldsShouldBeUsed()
+ .verify();
+ }
+
+ @Test
+ void firstShouldReturnAConstant() {
+ assertThat(EventId.first())
+ .isEqualTo(EventId.first());
+ }
+
+ @Test
+ void previousShouldReturnEmptyWhenBeforeFirst() {
+ assertThat(EventId.first().previous())
+ .isEmpty();
+ }
+
+ @Test
+ void compareToShouldReturnNegativeWhenComparedToNext() {
+ assertThat(EventId.first())
+ .isLessThan(EventId.first().next());
+ }
+
+ @Test
+ void compareToShouldReturnNegativeWhenComparedToPrevious() {
+ assertThat(EventId.first().next())
+ .isGreaterThan(EventId.first());
+ }
+
+ @Test
+ void nextShouldAlwaysHaveTheSameIncrement() {
+ assertThat(EventId.first().next())
+ .isEqualTo(EventId.first().next());
+ }
+
+ @Test
+ void previousShouldRevertNext() {
+ assertThat(EventId.first().next().previous())
+ .contains(EventId.first());
+ }
+
+ @Test
+ void compareToShouldReturnNegativeWhenComparedToNextWithPreviousCall() {
+ assertThat(EventId.first().next().previous().get())
+ .isLessThan(EventId.first().next());
+ }
+
+ @Test
+ void compareToShouldReturnNegativeWhenComparedToPreviousWithPreviousCall() {
+ assertThat(EventId.first().next())
+ .isGreaterThan(EventId.first().next().previous().get());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java b/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
new file mode 100644
index 0000000..b3ae78c
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
@@ -0,0 +1,68 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+public class TestAggregateId implements AggregateId {
+
+ public static TestAggregateId testId(int id) {
+ return new TestAggregateId(id);
+ }
+
+ private final int id;
+
+ private TestAggregateId(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public String asAggregateKey() {
+ return "TestAggregateId-" + id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof TestAggregateId) {
+ TestAggregateId that = (TestAggregateId) o;
+
+ return Objects.equals(this.id, that.id);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("id", id)
+ .toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestEvent.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestEvent.java b/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestEvent.java
new file mode 100644
index 0000000..c46f804
--- /dev/null
+++ b/event-sourcing/event-sourcing-pojo/src/test/java/org/apache/james/eventsourcing/TestEvent.java
@@ -0,0 +1,82 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing;
+
+import java.util.Comparator;
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+public class TestEvent implements Event {
+ private final EventId id;
+ private final TestAggregateId aggregateId;
+ private final String data;
+
+ public TestEvent(EventId id, TestAggregateId aggregateId, String data) {
+ this.id = id;
+ this.aggregateId = aggregateId;
+ this.data = data;
+ }
+
+ @Override
+ public EventId eventId() {
+ return id;
+ }
+
+ @Override
+ public TestAggregateId getAggregateId() {
+ return aggregateId;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ @Override
+ public int compareTo(Event o) {
+ return Comparator.<EventId>naturalOrder().compare(id, o.eventId());
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof TestEvent) {
+ TestEvent testEvent = (TestEvent) o;
+
+ return Objects.equals(this.id, testEvent.id)
+ && Objects.equals(this.aggregateId, testEvent.aggregateId)
+ && Objects.equals(this.data, testEvent.data);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, aggregateId, data);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("id", id)
+ .add("aggregateId", aggregateId)
+ .add("data", data)
+ .toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-api/pom.xml
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-api/pom.xml b/event-sourcing/event-store-api/pom.xml
new file mode 100644
index 0000000..2cfd710
--- /dev/null
+++ b/event-sourcing/event-store-api/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.james</groupId>
+ <artifactId>event-sourcing</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>event-sourcing-event-store-api</artifactId>
+
+ <name>Apache James :: Event Sourcing :: Event Store :: API</name>
+ <description>James Event Sourcing interface for Event Store implementations</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.github.steveash.guavate</groupId>
+ <artifactId>guavate</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>nl.jqno.equalsverifier</groupId>
+ <artifactId>equalsverifier</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-launcher</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStore.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStore.java b/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStore.java
new file mode 100644
index 0000000..3b3a95e
--- /dev/null
+++ b/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStore.java
@@ -0,0 +1,47 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore;
+
+import java.util.List;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+
+import com.google.common.collect.ImmutableList;
+
+public interface EventStore {
+
+ default void append(Event event) {
+ appendAll(ImmutableList.of(event));
+ }
+
+ default void appendAll(Event... events) {
+ appendAll(ImmutableList.copyOf(events));
+ }
+
+ /**
+ * This method should check that no input event has an id already stored and throw otherwise
+ * It should also check that all events belong to the same aggregate
+ */
+ void appendAll(List<Event> events);
+
+ History getEventsOfAggregate(AggregateId aggregateId);
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.java b/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.java
new file mode 100644
index 0000000..93bcb2f
--- /dev/null
+++ b/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.java
@@ -0,0 +1,23 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore;
+
+public class EventStoreFailedException extends RuntimeException {
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/History.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/History.java b/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/History.java
new file mode 100644
index 0000000..5a91306
--- /dev/null
+++ b/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/History.java
@@ -0,0 +1,94 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+
+import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableList;
+
+public class History {
+ public static History empty() {
+ return new History(ImmutableList.of());
+ }
+
+ public static History of(List<Event> events) {
+ return new History(ImmutableList.copyOf(events));
+ }
+
+ public static History of(Event... events) {
+ return of(ImmutableList.copyOf(events));
+ }
+
+ private final List<Event> events;
+
+ private History(List<Event> events) {
+ if (hasEventIdDuplicates(events)) {
+ throw new EventStoreFailedException();
+ }
+ this.events = events;
+ }
+
+ public boolean hasEventIdDuplicates(List<Event> events) {
+ Set<EventId> eventIds = events.stream()
+ .map(Event::eventId)
+ .collect(Guavate.toImmutableSet());
+
+ return eventIds.size() != events.size();
+ }
+
+ public Optional<EventId> getVersion() {
+ return events.stream()
+ .map(Event::eventId)
+ .max(Comparator.naturalOrder());
+ }
+
+ public List<Event> getEvents() {
+ return events;
+ }
+
+ public EventId getNextEventId() {
+ return getVersion()
+ .map(EventId::next)
+ .orElse(EventId.first());
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof History) {
+ History history = (History) o;
+
+ return Objects.equals(this.events, history.events);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(events);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/EventStoreTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/EventStoreTest.java b/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/EventStoreTest.java
new file mode 100644
index 0000000..dc312d9
--- /dev/null
+++ b/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/EventStoreTest.java
@@ -0,0 +1,88 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore;
+
+import static org.apache.james.eventsourcing.TestAggregateId.testId;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+import org.apache.james.eventsourcing.TestEvent;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public interface EventStoreTest {
+
+ TestAggregateId AGGREGATE_1 = testId(1);
+ TestAggregateId AGGREGATE_2 = testId(2);
+
+ @Test
+ default void getEventsOfAggregateShouldThrowOnNullAggregateId(EventStore testee) {
+ assertThatThrownBy(() -> testee.getEventsOfAggregate(null))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ default void appendShouldThrowWhenEventFromSeveralAggregates(EventStore testee) {
+ TestEvent event1 = new TestEvent(EventId.first(), AGGREGATE_1, "first");
+ TestEvent event2 = new TestEvent(event1.eventId().next(), AGGREGATE_2, "second");
+ assertThatThrownBy(() -> testee.appendAll(event1, event2)).isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ default void appendShouldDoNothingOnEmptyEventList(EventStore testee) {
+ assertThatCode(testee::appendAll).doesNotThrowAnyException();
+ }
+
+ @Test
+ default void appendShouldThrowWhenTryingToRewriteHistory(EventStore testee) {
+ TestEvent event1 = new TestEvent(EventId.first(), AGGREGATE_1, "first");
+ testee.append(event1);
+ TestEvent event2 = new TestEvent(EventId.first(), AGGREGATE_1, "second");
+ assertThatThrownBy(() -> testee.append(event2)).isInstanceOf(EventStoreFailedException.class);
+ }
+
+ @Test
+ default void getEventsOfAggregateShouldReturnEmptyHistoryWhenUnknown(EventStore testee) {
+ assertThat(testee.getEventsOfAggregate(AGGREGATE_1)).isEqualTo(History.empty());
+ }
+
+ @Test
+ default void getEventsOfAggregateShouldReturnAppendedEvent(EventStore testee) {
+ TestEvent event = new TestEvent(EventId.first(), AGGREGATE_1, "first");
+ testee.append(event);
+ assertThat(testee.getEventsOfAggregate(AGGREGATE_1))
+ .isEqualTo(History.of(ImmutableList.of(event)));
+ }
+
+ @Test
+ default void getEventsOfAggregateShouldReturnAppendedEvents(EventStore testee) {
+ TestEvent event1 = new TestEvent(EventId.first(), AGGREGATE_1, "first");
+ TestEvent event2 = new TestEvent(event1.eventId().next(), AGGREGATE_1, "second");
+ testee.append(event1);
+ testee.append(event2);
+ assertThat(testee.getEventsOfAggregate(AGGREGATE_1))
+ .isEqualTo(History.of(ImmutableList.of(event1, event2)));
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/HistoryTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/HistoryTest.java b/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/HistoryTest.java
new file mode 100644
index 0000000..2945b92
--- /dev/null
+++ b/event-sourcing/event-store-api/src/test/java/org/apache/james/eventsourcing/eventstore/HistoryTest.java
@@ -0,0 +1,91 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+import org.apache.james.eventsourcing.TestEvent;
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class HistoryTest {
+
+ @Test
+ void shouldMatchBeanContract() {
+ EqualsVerifier.forClass(History.class)
+ .allFieldsShouldBeUsed()
+ .verify();
+ }
+
+ @Test
+ void emptyShouldGenerateAnEmptyHistory() {
+ assertThat(History.empty())
+ .isEqualTo(History.of());
+ }
+
+ @Test
+ void getVersionShouldReturnEmptyWhenEmpty() {
+ assertThat(History.empty()
+ .getVersion())
+ .isEmpty();
+ }
+
+ @Test
+ void getVersionShouldReturnSingleEventIdWhenSingleEvent() {
+ assertThat(History
+ .of(new TestEvent(EventId.first(),
+ TestAggregateId.testId(42),
+ "any"))
+ .getVersion())
+ .contains(EventId.first());
+ }
+
+ @Test
+ void getVersionShouldReturnHighestEventId() {
+ TestEvent event1 = new TestEvent(EventId.first(),
+ TestAggregateId.testId(42),
+ "any");
+ TestEvent event2 = new TestEvent(event1.eventId().next(),
+ TestAggregateId.testId(42),
+ "any");
+
+ assertThat(History.of(event1, event2)
+ .getVersion())
+ .contains(event2.eventId());
+ }
+
+ @Test
+ void duplicateHistoryShouldThrow() {
+ TestEvent event1 = new TestEvent(EventId.first(),
+ TestAggregateId.testId(42),
+ "any");
+ TestEvent event2 = new TestEvent(EventId.first(),
+ TestAggregateId.testId(42),
+ "any");
+
+ assertThatThrownBy(() -> History.of(event1, event2))
+ .isInstanceOf(EventStoreFailedException.class);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/pom.xml b/event-sourcing/event-store-cassandra/pom.xml
new file mode 100644
index 0000000..cf2e6dc
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/pom.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.james</groupId>
+ <artifactId>event-sourcing</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>event-sourcing-event-store-cassandra</artifactId>
+
+ <name>Apache James :: Event sourcing :: Event Store :: Cassandra</name>
+ <description>Cassandra implementation for James Event Store</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apache-james-backends-cassandra</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apache-james-backends-cassandra</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jdk8</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.javacrumbs.json-unit</groupId>
+ <artifactId>json-unit</artifactId>
+ <version>1.5.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.javacrumbs.json-unit</groupId>
+ <artifactId>json-unit-fluent</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>nl.jqno.equalsverifier</groupId>
+ <artifactId>equalsverifier</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-launcher</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>testcontainers</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+
+</project>
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[3/4] james-project git commit: JAMES-2393 Introduce dedicated
modules for event sourcing
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStore.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStore.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStore.java
new file mode 100644
index 0000000..0e8fd5f
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStore.java
@@ -0,0 +1,64 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.EventStore;
+import org.apache.james.eventsourcing.eventstore.EventStoreFailedException;
+import org.apache.james.eventsourcing.eventstore.History;
+
+import com.google.common.base.Preconditions;
+
+public class CassandraEventStore implements EventStore {
+
+ private final EventStoreDao eventStoreDao;
+
+ @Inject
+ public CassandraEventStore(EventStoreDao eventStoreDao) {
+ this.eventStoreDao = eventStoreDao;
+ }
+
+ @Override
+ public void appendAll(List<Event> events) {
+ if (events.isEmpty()) {
+ return;
+ }
+ doAppendAll(events);
+ }
+
+ public void doAppendAll(List<Event> events) {
+ Preconditions.checkArgument(Event.belongsToSameAggregate(events));
+
+ boolean success = eventStoreDao.appendAll(events).join();
+ if (!success) {
+ throw new EventStoreFailedException();
+ }
+ }
+
+ @Override
+ public History getEventsOfAggregate(AggregateId aggregateId) {
+ return eventStoreDao.getEventsOfAggregate(aggregateId);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreModule.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreModule.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreModule.java
new file mode 100644
index 0000000..85dab3c
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreModule.java
@@ -0,0 +1,62 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import java.util.List;
+
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraTable;
+import org.apache.james.backends.cassandra.components.CassandraType;
+import org.apache.james.backends.cassandra.utils.CassandraConstants;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+import com.google.common.collect.ImmutableList;
+
+public class CassandraEventStoreModule implements CassandraModule {
+ private final List<CassandraTable> tables;
+ private final List<CassandraType> types;
+
+ public CassandraEventStoreModule() {
+ tables = ImmutableList.of(
+ new CassandraTable(CassandraEventStoreTable.EVENTS_TABLE,
+ SchemaBuilder.createTable(CassandraEventStoreTable.EVENTS_TABLE)
+ .ifNotExists()
+ .addPartitionKey(CassandraEventStoreTable.AGGREGATE_ID, DataType.varchar())
+ .addClusteringColumn(CassandraEventStoreTable.EVENT_ID, DataType.cint())
+ .addColumn(CassandraEventStoreTable.EVENT, DataType.text())
+ .withOptions()
+ .comment("Store events of a EventSourcing aggregate")
+ .caching(SchemaBuilder.KeyCaching.ALL,
+ SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION))));
+ types = ImmutableList.of();
+ }
+
+ @Override
+ public List<CassandraTable> moduleTables() {
+ return tables;
+ }
+
+ @Override
+ public List<CassandraType> moduleTypes() {
+ return types;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTable.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTable.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTable.java
new file mode 100644
index 0000000..fb4575b
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTable.java
@@ -0,0 +1,27 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+public interface CassandraEventStoreTable {
+ String EVENTS_TABLE = "eventStore";
+ String AGGREGATE_ID = "aggregateId";
+ String EVENT = "event";
+ String EVENT_ID = "eventId";
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventStoreDao.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventStoreDao.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventStoreDao.java
new file mode 100644
index 0000000..feb6ef7
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/EventStoreDao.java
@@ -0,0 +1,122 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreTable.AGGREGATE_ID;
+import static org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreTable.EVENT;
+import static org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreTable.EVENTS_TABLE;
+import static org.apache.james.eventsourcing.eventstore.cassandra.CassandraEventStoreTable.EVENT_ID;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.History;
+
+import com.datastax.driver.core.BatchStatement;
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.github.steveash.guavate.Guavate;
+
+public class EventStoreDao {
+ private final CassandraUtils cassandraUtils;
+ private final CassandraAsyncExecutor cassandraAsyncExecutor;
+ private final PreparedStatement insert;
+ private final PreparedStatement select;
+ private final JsonEventSerializer jsonEventSerializer;
+
+ @Inject
+ public EventStoreDao(Session session, CassandraUtils cassandraUtils, JsonEventSerializer jsonEventSerializer) {
+ this.cassandraUtils = cassandraUtils;
+ this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
+ this.jsonEventSerializer = jsonEventSerializer;
+ this.insert = prepareInsert(session);
+ this.select = prepareSelect(session);
+ }
+
+ private PreparedStatement prepareInsert(Session session) {
+ return session.prepare(insertInto(EVENTS_TABLE)
+ .value(AGGREGATE_ID, bindMarker(AGGREGATE_ID))
+ .value(EVENT_ID, bindMarker(EVENT_ID))
+ .value(EVENT, bindMarker(EVENT))
+ .ifNotExists());
+ }
+
+ private PreparedStatement prepareSelect(Session session) {
+ return session.prepare(select()
+ .from(EVENTS_TABLE)
+ .where(eq(AGGREGATE_ID, bindMarker(AGGREGATE_ID))));
+ }
+
+ public CompletableFuture<Boolean> appendAll(List<Event> events) {
+ BatchStatement batch = new BatchStatement();
+ events.forEach(event -> batch.add(insertEvent(event)));
+ return cassandraAsyncExecutor.executeReturnApplied(batch);
+ }
+
+ private BoundStatement insertEvent(Event event) {
+ try {
+ return insert
+ .bind()
+ .setString(AGGREGATE_ID, event.getAggregateId().asAggregateKey())
+ .setInt(EVENT_ID, event.eventId().serialize())
+ .setString(EVENT, jsonEventSerializer.serialize(event));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public History getEventsOfAggregate(AggregateId aggregateId) {
+ return toHistory(
+ cassandraAsyncExecutor.execute(
+ select.bind()
+ .setString(AGGREGATE_ID, aggregateId.asAggregateKey()))
+ .join());
+ }
+
+ private History toHistory(ResultSet resultSet) {
+ List<Event> events = cassandraUtils.convertToStream(resultSet)
+ .map(this::toEvent)
+ .collect(Guavate.toImmutableList());
+ return History.of(events);
+ }
+
+ private Event toEvent(Row row) {
+ try {
+ return jsonEventSerializer.deserialize(row.getString(EVENT));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
new file mode 100644
index 0000000..dea4a5e
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializer.java
@@ -0,0 +1,98 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+
+import javax.inject.Inject;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableSet;
+
+public class JsonEventSerializer {
+ public static class UnknownEventException extends RuntimeException {
+ public UnknownEventException(String message) {
+ super(message);
+ }
+ }
+
+ private final Map<Class<? extends Event>, EventDTOModule> eventClassToModule;
+ private final Map<String, EventDTOModule> typeToModule;
+ private final ObjectMapper objectMapper;
+
+ @Inject
+ public JsonEventSerializer(Set<EventDTOModule> modules) {
+ objectMapper = new ObjectMapper();
+ objectMapper.registerModule(new Jdk8Module());
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+
+ typeToModule = modules.stream()
+ .collect(Guavate.toImmutableMap(
+ EventDTOModule::getType,
+ Function.identity()));
+
+ eventClassToModule = modules.stream()
+ .collect(Guavate.toImmutableMap(
+ EventDTOModule::getEventClass,
+ Function.identity()));
+ }
+
+ public JsonEventSerializer(EventDTOModule... modules) {
+ this(ImmutableSet.copyOf(modules));
+ }
+
+ public String serialize(Event event) throws JsonProcessingException {
+ Object dto = Optional.ofNullable(eventClassToModule.get(event.getClass()))
+ .orElseThrow(() -> new UnknownEventException("unknown event class " + event.getClass()))
+ .toDTO(event);
+ return objectMapper.writeValueAsString(dto);
+ }
+
+ public Event deserialize(String value) throws IOException {
+ JsonNode jsonNode = objectMapper.readTree(value);
+
+ String type = jsonNode.path("type").asText();
+
+ EventDTO dto = objectMapper.readValue(
+ objectMapper.treeAsTokens(jsonNode),
+ retrieveDTOClass(type));
+ return dto.toEvent();
+ }
+
+ public Class<? extends EventDTO> retrieveDTOClass(String type) {
+ return Optional.ofNullable(typeToModule.get(type))
+ .map(EventDTOModule::getDTOClass)
+ .orElseThrow(() -> new UnknownEventException("unknown event type " + type));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTO.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTO.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTO.java
new file mode 100644
index 0000000..461212a
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTO.java
@@ -0,0 +1,26 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+
+public interface EventDTO {
+ Event toEvent();
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTOModule.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTOModule.java b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTOModule.java
new file mode 100644
index 0000000..feaa5ef
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/main/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/EventDTOModule.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+
+public interface EventDTOModule {
+ String getType();
+
+ Class<? extends EventDTO> getDTOClass();
+
+ Class<? extends Event> getEventClass();
+
+ EventDTO toDTO(Event event);
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java
new file mode 100644
index 0000000..e538b93
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventSourcingSystemTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import org.apache.james.eventsourcing.EventSourcingSystemTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(CassandraEventStoreExtension.class)
+public class CassandraEventSourcingSystemTest implements EventSourcingSystemTest {
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java
new file mode 100644
index 0000000..73754a9
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreExtension.java
@@ -0,0 +1,30 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.TestEventDTOModule;
+
+import com.google.common.collect.ImmutableSet;
+
+public class CassandraEventStoreExtension extends CassandraGenericEventStoreExtension {
+ public CassandraEventStoreExtension() {
+ super(ImmutableSet.of(new TestEventDTOModule()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java
new file mode 100644
index 0000000..6d240c3
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraEventStoreTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import org.apache.james.eventsourcing.eventstore.EventStoreTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(CassandraEventStoreExtension.class)
+class CassandraEventStoreTest implements EventStoreTest {
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraGenericEventStoreExtension.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraGenericEventStoreExtension.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraGenericEventStoreExtension.java
new file mode 100644
index 0000000..699153d
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/CassandraGenericEventStoreExtension.java
@@ -0,0 +1,87 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import java.util.Set;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.DockerCassandraExtension;
+import org.apache.james.backends.cassandra.DockerCassandraExtension.DockerCassandra;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.eventsourcing.eventstore.EventStore;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class CassandraGenericEventStoreExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {
+ private final DockerCassandraExtension dockerCassandraExtension;
+ private final Set<EventDTOModule> modules;
+ private CassandraCluster cassandra;
+ private DockerCassandra dockerCassandra;
+ private EventStoreDao eventStoreDao;
+
+ public CassandraGenericEventStoreExtension(Set<EventDTOModule> modules) {
+ this.modules = modules;
+ dockerCassandraExtension = new DockerCassandraExtension();
+ }
+
+ @Override
+ public void beforeAll(ExtensionContext context) throws Exception {
+ dockerCassandraExtension.beforeAll(context);
+ dockerCassandra = dockerCassandraExtension.getDockerCassandra();
+ }
+
+ @Override
+ public void afterAll(ExtensionContext context) throws Exception {
+ dockerCassandraExtension.afterAll(context);
+ }
+
+ @Override
+ public void beforeEach(ExtensionContext context) {
+ cassandra = CassandraCluster.create(
+ new CassandraEventStoreModule(), dockerCassandra.getIp(), dockerCassandra.getBindingPort());
+
+ JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(modules);
+
+ eventStoreDao = new EventStoreDao(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION,
+ jsonEventSerializer);
+ }
+
+ @Override
+ public void afterEach(ExtensionContext context) {
+ cassandra.close();
+ }
+
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+ return (parameterContext.getParameter().getType() == EventStore.class);
+ }
+
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+ return new CassandraEventStore(eventStoreDao);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java
new file mode 100644
index 0000000..1664ab1
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/JsonEventSerializerTest.java
@@ -0,0 +1,102 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra;
+
+import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+import org.apache.james.eventsourcing.TestEvent;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.OtherEvent;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.OtherTestEventDTOModule;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.TestEventDTOModule;
+import org.junit.jupiter.api.Test;
+
+class JsonEventSerializerTest {
+ public static final EventId EVENT_ID = EventId.fromSerialized(0);
+ public static final TestAggregateId AGGREGATE_ID = TestAggregateId.testId(1);
+
+ public static final OtherEvent OTHER_EVENT = new OtherEvent(EVENT_ID, AGGREGATE_ID, 1);
+ public static final TestEvent TEST_EVENT = new TestEvent(EVENT_ID, AGGREGATE_ID, "first");
+
+ public static final String TEST_EVENT_JSON = "{\"type\":\"TestType\",\"data\":\"first\",\"eventId\":0,\"aggregate\":1}";
+ public static final String OTHER_EVENT_JSON = "{\"type\":\"other-type\",\"data\":1,\"eventId\":0,\"aggregate\":1}";
+
+ @Test
+ void shouldDeserializeKnownEvent() throws Exception {
+ assertThat(new JsonEventSerializer(new TestEventDTOModule())
+ .deserialize(TEST_EVENT_JSON))
+ .isEqualTo(TEST_EVENT);
+ }
+
+ @Test
+ void shouldThrowWhenDeserializeUnknownEvent() {
+ assertThatThrownBy(() -> new JsonEventSerializer()
+ .deserialize(TEST_EVENT_JSON))
+ .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
+ }
+
+ @Test
+ void serializeShouldHandleAllKnownEvents() throws Exception {
+ JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
+ new TestEventDTOModule(),
+ new OtherTestEventDTOModule());
+
+ assertThatJson(
+ jsonEventSerializer.serialize(OTHER_EVENT))
+ .isEqualTo(OTHER_EVENT_JSON);
+
+ assertThatJson(
+ jsonEventSerializer.serialize(TEST_EVENT))
+ .isEqualTo(TEST_EVENT_JSON);
+ }
+
+ @Test
+ void deserializeShouldHandleAllKnownEvents() throws Exception {
+ JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
+ new TestEventDTOModule(),
+ new OtherTestEventDTOModule());
+
+ assertThatJson(
+ jsonEventSerializer.deserialize(OTHER_EVENT_JSON))
+ .isEqualTo(OTHER_EVENT);
+
+ assertThatJson(
+ jsonEventSerializer.deserialize(TEST_EVENT_JSON))
+ .isEqualTo(TEST_EVENT);
+ }
+
+ @Test
+ void shouldSerializeKnownEvent() throws Exception {
+ assertThatJson(new JsonEventSerializer(new TestEventDTOModule())
+ .serialize(TEST_EVENT))
+ .isEqualTo(TEST_EVENT_JSON);
+ }
+
+ @Test
+ void shouldThrowWhenSerializeUnknownEvent() {
+ assertThatThrownBy(() -> new JsonEventSerializer()
+ .serialize(TEST_EVENT))
+ .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherEvent.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherEvent.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherEvent.java
new file mode 100644
index 0000000..1b21a36
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherEvent.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+
+public class OtherEvent implements Event {
+ private final EventId eventId;
+ private final TestAggregateId aggregateId;
+ private final long payload;
+
+ public OtherEvent(EventId eventId, TestAggregateId aggregateId, long payload) {
+ this.eventId = eventId;
+ this.aggregateId = aggregateId;
+ this.payload = payload;
+ }
+
+ @Override
+ public EventId eventId() {
+ return eventId;
+ }
+
+ @Override
+ public TestAggregateId getAggregateId() {
+ return aggregateId;
+ }
+
+ public long getPayload() {
+ return payload;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTO.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTO.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTO.java
new file mode 100644
index 0000000..d4739f8
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTO.java
@@ -0,0 +1,72 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class OtherTestEventDTO implements EventDTO {
+ private final String type;
+ private final long data;
+ private final int eventId;
+ private final int aggregate;
+
+ @JsonCreator
+ public OtherTestEventDTO(
+ @JsonProperty("type") String type,
+ @JsonProperty("data") long data,
+ @JsonProperty("eventId") int eventId,
+ @JsonProperty("aggregate") int aggregate) {
+ this.type = type;
+ this.data = data;
+ this.eventId = eventId;
+ this.aggregate = aggregate;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public long getData() {
+ return data;
+ }
+
+ public long getEventId() {
+ return eventId;
+ }
+
+ public int getAggregate() {
+ return aggregate;
+ }
+
+ @JsonIgnore
+ @Override
+ public Event toEvent() {
+ return new OtherEvent(
+ EventId.fromSerialized(eventId),
+ TestAggregateId.testId(aggregate),
+ data);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTOModule.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTOModule.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTOModule.java
new file mode 100644
index 0000000..d025add
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/OtherTestEventDTOModule.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.testcontainers.shaded.com.google.common.base.Preconditions;
+
+public class OtherTestEventDTOModule implements EventDTOModule {
+
+ public static final String OTHER_TYPE = "other-type";
+
+ @Override
+ public String getType() {
+ return OTHER_TYPE;
+ }
+
+ @Override
+ public Class<? extends EventDTO> getDTOClass() {
+ return OtherTestEventDTO.class;
+ }
+
+ @Override
+ public Class<? extends Event> getEventClass() {
+ return OtherEvent.class;
+ }
+
+ @Override
+ public EventDTO toDTO(Event event) {
+ Preconditions.checkArgument(event instanceof OtherEvent);
+ OtherEvent otherEvent = (OtherEvent) event;
+
+ return new OtherTestEventDTO(
+ OTHER_TYPE,
+ otherEvent.getPayload(),
+ otherEvent.eventId().serialize(),
+ otherEvent.getAggregateId().getId());
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTO.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTO.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTO.java
new file mode 100644
index 0000000..709c709
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTO.java
@@ -0,0 +1,73 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+import org.apache.james.eventsourcing.TestEvent;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class TestEventDTO implements EventDTO {
+ private final String type;
+ private final String data;
+ private final int eventId;
+ private final int aggregate;
+
+ @JsonCreator
+ public TestEventDTO(
+ @JsonProperty("type") String type,
+ @JsonProperty("data") String data,
+ @JsonProperty("eventId") int eventId,
+ @JsonProperty("aggregate") int aggregate) {
+ this.type = type;
+ this.data = data;
+ this.eventId = eventId;
+ this.aggregate = aggregate;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public long getEventId() {
+ return eventId;
+ }
+
+ public int getAggregate() {
+ return aggregate;
+ }
+
+ @JsonIgnore
+ @Override
+ public Event toEvent() {
+ return new TestEvent(
+ EventId.fromSerialized(eventId),
+ TestAggregateId.testId(aggregate),
+ data);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTOModule.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTOModule.java b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTOModule.java
new file mode 100644
index 0000000..f0613ee
--- /dev/null
+++ b/event-sourcing/event-store-cassandra/src/test/java/org/apache/james/eventsourcing/eventstore/cassandra/dto/TestEventDTOModule.java
@@ -0,0 +1,56 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.TestEvent;
+import org.testcontainers.shaded.com.google.common.base.Preconditions;
+
+public class TestEventDTOModule implements EventDTOModule {
+
+ public static final String TEST_TYPE = "TestType";
+
+ @Override
+ public String getType() {
+ return TEST_TYPE;
+ }
+
+ @Override
+ public Class<? extends EventDTO> getDTOClass() {
+ return TestEventDTO.class;
+ }
+
+ @Override
+ public Class<? extends Event> getEventClass() {
+ return TestEvent.class;
+ }
+
+ @Override
+ public EventDTO toDTO(Event event) {
+ Preconditions.checkArgument(event instanceof TestEvent);
+
+ TestEvent testEvent = (TestEvent) event;
+ return new TestEventDTO(
+ TEST_TYPE,
+ testEvent.getData(),
+ testEvent.eventId().serialize(),
+ testEvent.getAggregateId().getId());
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-memory/pom.xml
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-memory/pom.xml b/event-sourcing/event-store-memory/pom.xml
new file mode 100644
index 0000000..c23c93a
--- /dev/null
+++ b/event-sourcing/event-store-memory/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.james</groupId>
+ <artifactId>event-sourcing</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+
+ <name>Apache James :: Event sourcing :: Event Store :: Memory</name>
+ <description>Memory implementation for James Event Store</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-pojo</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-launcher</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-memory/src/main/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStore.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-memory/src/main/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStore.java b/event-sourcing/event-store-memory/src/main/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStore.java
new file mode 100644
index 0000000..69ccf5f
--- /dev/null
+++ b/event-sourcing/event-store-memory/src/main/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStore.java
@@ -0,0 +1,99 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.memory;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.EventStore;
+import org.apache.james.eventsourcing.eventstore.EventStoreFailedException;
+import org.apache.james.eventsourcing.eventstore.History;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+public class InMemoryEventStore implements EventStore {
+
+ private final ConcurrentHashMap<AggregateId, History> store;
+
+ public InMemoryEventStore() {
+ this.store = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ public void appendAll(List<Event> events) {
+ if (events.isEmpty()) {
+ return;
+ }
+ AggregateId aggregateId = getAggregateId(events);
+
+ if (!store.containsKey(aggregateId)) {
+ appendToEmptyHistory(aggregateId, events);
+ } else {
+ appendToExistingHistory(aggregateId, events);
+ }
+ }
+
+ private AggregateId getAggregateId(List<? extends Event> events) {
+ Preconditions.checkArgument(!events.isEmpty());
+ Preconditions.checkArgument(Event.belongsToSameAggregate(events));
+
+ return events.stream()
+ .map(Event::getAggregateId)
+ .findFirst()
+ .get();
+ }
+
+ private void appendToEmptyHistory(AggregateId aggregateId, List<Event> events) {
+ History newHistory = History.of(events);
+
+ History previousHistory = store.putIfAbsent(aggregateId, newHistory);
+ if (previousHistory != null) {
+ throw new EventStoreFailedException();
+ }
+ }
+
+ private void appendToExistingHistory(AggregateId aggregateId, List<? extends Event> events) {
+ History currentHistory = store.get(aggregateId);
+ List<Event> updatedEvents = updatedEvents(currentHistory, events);
+ History updatedHistory = History.of(updatedEvents);
+
+ boolean isReplaced = store.replace(aggregateId, currentHistory, updatedHistory);
+ if (!isReplaced) {
+ throw new EventStoreFailedException();
+ }
+ }
+
+ private List<Event> updatedEvents(History currentHistory, List<? extends Event> newEvents) {
+ return ImmutableList.<Event>builder()
+ .addAll(currentHistory.getEvents())
+ .addAll(newEvents)
+ .build();
+ }
+
+ @Override
+ public History getEventsOfAggregate(AggregateId aggregateId) {
+ return Optional.ofNullable(store.get(aggregateId))
+ .orElse(History.empty());
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventSourcingSystemTest.java b/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventSourcingSystemTest.java
new file mode 100644
index 0000000..4a07c40
--- /dev/null
+++ b/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventSourcingSystemTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.memory;
+
+import org.apache.james.eventsourcing.EventSourcingSystemTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(InMemoryEventStoreExtension.class)
+public class InMemoryEventSourcingSystemTest implements EventSourcingSystemTest {
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreExtension.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreExtension.java b/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreExtension.java
new file mode 100644
index 0000000..03f61bc
--- /dev/null
+++ b/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreExtension.java
@@ -0,0 +1,39 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.memory;
+
+import org.apache.james.eventsourcing.eventstore.EventStore;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class InMemoryEventStoreExtension implements ParameterResolver {
+
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+ return (parameterContext.getParameter().getType() == EventStore.class);
+ }
+
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+ return new InMemoryEventStore();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreTest.java
----------------------------------------------------------------------
diff --git a/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreTest.java b/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreTest.java
new file mode 100644
index 0000000..11cd197
--- /dev/null
+++ b/event-sourcing/event-store-memory/src/test/java/org/apache/james/eventsourcing/eventstore/memory/InMemoryEventStoreTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.eventstore.memory;
+
+import org.apache.james.eventsourcing.eventstore.EventStoreTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(InMemoryEventStoreExtension.class)
+public class InMemoryEventStoreTest implements EventStoreTest {
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/event-sourcing/pom.xml
----------------------------------------------------------------------
diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml
new file mode 100644
index 0000000..920700b
--- /dev/null
+++ b/event-sourcing/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-project</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <packaging>pom</packaging>
+ <artifactId>event-sourcing</artifactId>
+
+ <name>Apache James :: Event Sourcing</name>
+
+ <modules>
+ <module>event-sourcing-core</module>
+ <module>event-sourcing-pojo</module>
+ <module>event-store-api</module>
+ <module>event-store-cassandra</module>
+ <module>event-store-memory</module>
+ </modules>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/pom.xml b/mailbox/plugin/quota-mailing-cassandra/pom.xml
index b6b3b2c..bc3b954 100644
--- a/mailbox/plugin/quota-mailing-cassandra/pom.xml
+++ b/mailbox/plugin/quota-mailing-cassandra/pom.xml
@@ -36,6 +36,27 @@
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-cassandra</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-cassandra</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
<artifactId>apache-james-backends-cassandra</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java
deleted file mode 100644
index 61c5a06..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.james.eventsourcing.AggregateId;
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.EventStore;
-
-import com.google.common.base.Preconditions;
-
-public class CassandraEventStore implements EventStore {
-
- private final EventStoreDao eventStoreDao;
-
- @Inject
- public CassandraEventStore(EventStoreDao eventStoreDao) {
- this.eventStoreDao = eventStoreDao;
- }
-
- @Override
- public void appendAll(List<Event> events) {
- if (events.isEmpty()) {
- return;
- }
- doAppendAll(events);
- }
-
- public void doAppendAll(List<Event> events) {
- Preconditions.checkArgument(Event.belongsToSameAggregate(events));
-
- boolean success = eventStoreDao.appendAll(events).join();
- if (!success) {
- throw new EventStoreFailedException();
- }
- }
-
- @Override
- public History getEventsOfAggregate(AggregateId aggregateId) {
- return eventStoreDao.getEventsOfAggregate(aggregateId);
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java
deleted file mode 100644
index ed15cb2..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import java.util.List;
-
-import org.apache.james.backends.cassandra.components.CassandraModule;
-import org.apache.james.backends.cassandra.components.CassandraTable;
-import org.apache.james.backends.cassandra.components.CassandraType;
-import org.apache.james.backends.cassandra.utils.CassandraConstants;
-
-import com.datastax.driver.core.DataType;
-import com.datastax.driver.core.schemabuilder.SchemaBuilder;
-import com.google.common.collect.ImmutableList;
-
-public class CassandraEventStoreModule implements CassandraModule {
- private final List<CassandraTable> tables;
- private final List<CassandraType> types;
-
- public CassandraEventStoreModule() {
- tables = ImmutableList.of(
- new CassandraTable(CassandraEventStoreTable.EVENTS_TABLE,
- SchemaBuilder.createTable(CassandraEventStoreTable.EVENTS_TABLE)
- .ifNotExists()
- .addPartitionKey(CassandraEventStoreTable.AGGREGATE_ID, DataType.varchar())
- .addClusteringColumn(CassandraEventStoreTable.EVENT_ID, DataType.cint())
- .addColumn(CassandraEventStoreTable.EVENT, DataType.text())
- .withOptions()
- .comment("Store events of a EventSourcing aggregate")
- .caching(SchemaBuilder.KeyCaching.ALL,
- SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION))));
- types = ImmutableList.of();
- }
-
- @Override
- public List<CassandraTable> moduleTables() {
- return tables;
- }
-
- @Override
- public List<CassandraType> moduleTypes() {
- return types;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java
deleted file mode 100644
index c90b81e..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-public interface CassandraEventStoreTable {
- String EVENTS_TABLE = "eventStore";
- String AGGREGATE_ID = "aggregateId";
- String EVENT = "event";
- String EVENT_ID = "eventId";
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[2/4] james-project git commit: JAMES-2393 Introduce dedicated
modules for event sourcing
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java
deleted file mode 100644
index 2518f02..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
-import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.AGGREGATE_ID;
-import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.EVENT;
-import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.EVENTS_TABLE;
-import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.EVENT_ID;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-
-import javax.inject.Inject;
-
-import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.backends.cassandra.utils.CassandraUtils;
-import org.apache.james.eventsourcing.AggregateId;
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.EventStore;
-
-import com.datastax.driver.core.BatchStatement;
-import com.datastax.driver.core.BoundStatement;
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Row;
-import com.datastax.driver.core.Session;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.github.steveash.guavate.Guavate;
-
-public class EventStoreDao {
- private final CassandraUtils cassandraUtils;
- private final CassandraAsyncExecutor cassandraAsyncExecutor;
- private final PreparedStatement insert;
- private final PreparedStatement select;
- private final JsonEventSerializer jsonEventSerializer;
-
- @Inject
- public EventStoreDao(Session session, CassandraUtils cassandraUtils, JsonEventSerializer jsonEventSerializer) {
- this.cassandraUtils = cassandraUtils;
- this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
- this.jsonEventSerializer = jsonEventSerializer;
- this.insert = prepareInsert(session);
- this.select = prepareSelect(session);
- }
-
- private PreparedStatement prepareInsert(Session session) {
- return session.prepare(insertInto(EVENTS_TABLE)
- .value(AGGREGATE_ID, bindMarker(AGGREGATE_ID))
- .value(EVENT_ID, bindMarker(EVENT_ID))
- .value(EVENT, bindMarker(EVENT))
- .ifNotExists());
- }
-
- private PreparedStatement prepareSelect(Session session) {
- return session.prepare(select()
- .from(EVENTS_TABLE)
- .where(eq(AGGREGATE_ID, bindMarker(AGGREGATE_ID))));
- }
-
- public CompletableFuture<Boolean> appendAll(List<Event> events) {
- BatchStatement batch = new BatchStatement();
- events.forEach(event -> batch.add(insertEvent(event)));
- return cassandraAsyncExecutor.executeReturnApplied(batch);
- }
-
- private BoundStatement insertEvent(Event event) {
- try {
- return insert
- .bind()
- .setString(AGGREGATE_ID, event.getAggregateId().asAggregateKey())
- .setInt(EVENT_ID, event.eventId().serialize())
- .setString(EVENT, jsonEventSerializer.serialize(event));
- } catch (JsonProcessingException e) {
- throw new RuntimeException(e);
- }
- }
-
- public EventStore.History getEventsOfAggregate(AggregateId aggregateId) {
- return toHistory(
- cassandraAsyncExecutor.execute(
- select.bind()
- .setString(AGGREGATE_ID, aggregateId.asAggregateKey()))
- .join());
- }
-
- private EventStore.History toHistory(ResultSet resultSet) {
- List<Event> events = cassandraUtils.convertToStream(resultSet)
- .map(this::toEvent)
- .collect(Guavate.toImmutableList());
- return EventStore.History.of(events);
- }
-
- private Event toEvent(Row row) {
- try {
- return jsonEventSerializer.deserialize(row.getString(EVENT));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java
deleted file mode 100644
index bf3a5dc..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-
-import javax.inject.Inject;
-
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.cassandra.dto.EventDTO;
-import org.apache.james.eventsourcing.cassandra.dto.EventDTOModule;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.ImmutableSet;
-
-public class JsonEventSerializer {
- public static class UnknownEventException extends RuntimeException {
- public UnknownEventException(String message) {
- super(message);
- }
- }
-
- private final Map<Class<? extends Event>, EventDTOModule> eventClassToModule;
- private final Map<String, EventDTOModule> typeToModule;
- private final ObjectMapper objectMapper;
-
- @Inject
- public JsonEventSerializer(Set<EventDTOModule> modules) {
- objectMapper = new ObjectMapper();
- objectMapper.registerModule(new Jdk8Module());
- objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
-
- typeToModule = modules.stream()
- .collect(Guavate.toImmutableMap(
- EventDTOModule::getType,
- Function.identity()));
-
- eventClassToModule = modules.stream()
- .collect(Guavate.toImmutableMap(
- EventDTOModule::getEventClass,
- Function.identity()));
- }
-
- public JsonEventSerializer(EventDTOModule... modules) {
- this(ImmutableSet.copyOf(modules));
- }
-
- public String serialize(Event event) throws JsonProcessingException {
- Object dto = Optional.ofNullable(eventClassToModule.get(event.getClass()))
- .orElseThrow(() -> new UnknownEventException("unknown event class " + event.getClass()))
- .toDTO(event);
- return objectMapper.writeValueAsString(dto);
- }
-
- public Event deserialize(String value) throws IOException {
- JsonNode jsonNode = objectMapper.readTree(value);
-
- String type = jsonNode.path("type").asText();
-
- EventDTO dto = objectMapper.readValue(
- objectMapper.treeAsTokens(jsonNode),
- retrieveDTOClass(type));
- return dto.toEvent();
- }
-
- public Class<? extends EventDTO> retrieveDTOClass(String type) {
- return Optional.ofNullable(typeToModule.get(type))
- .map(EventDTOModule::getDTOClass)
- .orElseThrow(() -> new UnknownEventException("unknown event type " + type));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java
deleted file mode 100644
index 4616248..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra.dto;
-
-import org.apache.james.eventsourcing.Event;
-
-public interface EventDTO {
- Event toEvent();
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java
deleted file mode 100644
index d86d1d7..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra.dto;
-
-import org.apache.james.eventsourcing.Event;
-
-public interface EventDTOModule {
- String getType();
-
- Class<? extends EventDTO> getDTOClass();
-
- Class<? extends Event> getEventClass();
-
- EventDTO toDTO(Event event);
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java
index 80eae8d..f229e2c 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java
@@ -21,7 +21,7 @@ package org.apache.james.mailbox.quota.cassandra.dto;
import org.apache.james.core.User;
import org.apache.james.eventsourcing.EventId;
-import org.apache.james.eventsourcing.cassandra.dto.EventDTO;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
import org.apache.james.mailbox.quota.mailing.aggregates.UserQuotaThresholds;
import org.apache.james.mailbox.quota.mailing.events.QuotaThresholdChangedEvent;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java
index 328cb09..7c37b7f 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java
@@ -20,8 +20,8 @@
package org.apache.james.mailbox.quota.cassandra.dto;
import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.cassandra.dto.EventDTO;
-import org.apache.james.eventsourcing.cassandra.dto.EventDTOModule;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTO;
+import org.apache.james.eventsourcing.eventstore.cassandra.dto.EventDTOModule;
import org.apache.james.mailbox.quota.mailing.events.QuotaThresholdChangedEvent;
import com.google.common.base.Preconditions;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java
deleted file mode 100644
index bee6e88..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import org.apache.james.eventsourcing.EventSourcingSystemTest;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-@ExtendWith(CassandraEventStoreExtension.class)
-public class CassandraEventSourcingSystemTest implements EventSourcingSystemTest {
-
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java
deleted file mode 100644
index 1b0066f..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import org.apache.james.backends.cassandra.CassandraCluster;
-import org.apache.james.backends.cassandra.DockerCassandraExtension;
-import org.apache.james.backends.cassandra.DockerCassandraExtension.DockerCassandra;
-import org.apache.james.backends.cassandra.utils.CassandraUtils;
-import org.apache.james.eventsourcing.EventStore;
-import org.apache.james.eventsourcing.cassandra.dto.TestEventDTOModule;
-import org.apache.james.mailbox.quota.cassandra.dto.QuotaThresholdChangedEventDTOModule;
-import org.junit.jupiter.api.extension.AfterAllCallback;
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-
-public class CassandraEventStoreExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {
- private final DockerCassandraExtension dockerCassandraExtension;
- private CassandraCluster cassandra;
- private DockerCassandra dockerCassandra;
- private EventStoreDao eventStoreDao;
-
- public CassandraEventStoreExtension() {
- dockerCassandraExtension = new DockerCassandraExtension();
- }
-
- @Override
- public void beforeAll(ExtensionContext context) throws Exception {
- dockerCassandraExtension.beforeAll(context);
- dockerCassandra = dockerCassandraExtension.getDockerCassandra();
- }
-
- @Override
- public void afterAll(ExtensionContext context) throws Exception {
- dockerCassandraExtension.afterAll(context);
- }
-
- @Override
- public void beforeEach(ExtensionContext context) {
- cassandra = CassandraCluster.create(
- new CassandraEventStoreModule(), dockerCassandra.getIp(), dockerCassandra.getBindingPort());
-
- JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
- new QuotaThresholdChangedEventDTOModule(),
- new TestEventDTOModule());
-
- eventStoreDao = new EventStoreDao(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION,
- jsonEventSerializer);
- }
-
- @Override
- public void afterEach(ExtensionContext context) {
- cassandra.close();
- }
-
- @Override
- public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return (parameterContext.getParameter().getType() == EventStore.class);
- }
-
- @Override
- public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return new CassandraEventStore(eventStoreDao);
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java
deleted file mode 100644
index 314b185..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import org.apache.james.eventsourcing.EventStoreTest;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-@ExtendWith(CassandraEventStoreExtension.class)
-class CassandraEventStoreTest implements EventStoreTest {
-
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
deleted file mode 100644
index 89770bb..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra;
-
-import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.apache.james.eventsourcing.EventId;
-import org.apache.james.eventsourcing.TestAggregateId;
-import org.apache.james.eventsourcing.TestEvent;
-import org.apache.james.eventsourcing.cassandra.dto.OtherEvent;
-import org.apache.james.eventsourcing.cassandra.dto.OtherTestEventDTOModule;
-import org.apache.james.eventsourcing.cassandra.dto.TestEventDTOModule;
-import org.junit.jupiter.api.Test;
-
-class JsonEventSerializerTest {
- public static final EventId EVENT_ID = EventId.fromSerialized(0);
- public static final TestAggregateId AGGREGATE_ID = TestAggregateId.testId(1);
-
- public static final OtherEvent OTHER_EVENT = new OtherEvent(EVENT_ID, AGGREGATE_ID, 1);
- public static final TestEvent TEST_EVENT = new TestEvent(EVENT_ID, AGGREGATE_ID, "first");
-
- public static final String TEST_EVENT_JSON = "{\"type\":\"TestType\",\"data\":\"first\",\"eventId\":0,\"aggregate\":1}";
- public static final String OTHER_EVENT_JSON = "{\"type\":\"other-type\",\"data\":1,\"eventId\":0,\"aggregate\":1}";
-
- @Test
- void shouldDeserializeKnownEvent() throws Exception {
- assertThat(new JsonEventSerializer(new TestEventDTOModule())
- .deserialize(TEST_EVENT_JSON))
- .isEqualTo(TEST_EVENT);
- }
-
- @Test
- void shouldThrowWhenDeserializeUnknownEvent() {
- assertThatThrownBy(() -> new JsonEventSerializer()
- .deserialize(TEST_EVENT_JSON))
- .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
- }
-
- @Test
- void serializeShouldHandleAllKnownEvents() throws Exception {
- JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
- new TestEventDTOModule(),
- new OtherTestEventDTOModule());
-
- assertThatJson(
- jsonEventSerializer.serialize(OTHER_EVENT))
- .isEqualTo(OTHER_EVENT_JSON);
-
- assertThatJson(
- jsonEventSerializer.serialize(TEST_EVENT))
- .isEqualTo(TEST_EVENT_JSON);
- }
-
- @Test
- void deserializeShouldHandleAllKnownEvents() throws Exception {
- JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
- new TestEventDTOModule(),
- new OtherTestEventDTOModule());
-
- assertThatJson(
- jsonEventSerializer.deserialize(OTHER_EVENT_JSON))
- .isEqualTo(OTHER_EVENT);
-
- assertThatJson(
- jsonEventSerializer.deserialize(TEST_EVENT_JSON))
- .isEqualTo(TEST_EVENT);
- }
-
- @Test
- void shouldSerializeKnownEvent() throws Exception {
- assertThatJson(new JsonEventSerializer(new TestEventDTOModule())
- .serialize(TEST_EVENT))
- .isEqualTo(TEST_EVENT_JSON);
- }
-
- @Test
- void shouldThrowWhenSerializeUnknownEvent() {
- assertThatThrownBy(() -> new JsonEventSerializer()
- .serialize(TEST_EVENT))
- .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java
deleted file mode 100644
index 4e74720..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra.dto;
-
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.EventId;
-import org.apache.james.eventsourcing.TestAggregateId;
-
-public class OtherEvent implements Event {
- private final EventId eventId;
- private final TestAggregateId aggregateId;
- private final long payload;
-
- public OtherEvent(EventId eventId, TestAggregateId aggregateId, long payload) {
- this.eventId = eventId;
- this.aggregateId = aggregateId;
- this.payload = payload;
- }
-
- @Override
- public EventId eventId() {
- return eventId;
- }
-
- @Override
- public TestAggregateId getAggregateId() {
- return aggregateId;
- }
-
- public long getPayload() {
- return payload;
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java
deleted file mode 100644
index 4f35c12..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra.dto;
-
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.EventId;
-import org.apache.james.eventsourcing.TestAggregateId;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class OtherTestEventDTO implements EventDTO {
- private final String type;
- private final long data;
- private final int eventId;
- private final int aggregate;
-
- @JsonCreator
- public OtherTestEventDTO(
- @JsonProperty("type") String type,
- @JsonProperty("data") long data,
- @JsonProperty("eventId") int eventId,
- @JsonProperty("aggregate") int aggregate) {
- this.type = type;
- this.data = data;
- this.eventId = eventId;
- this.aggregate = aggregate;
- }
-
- public String getType() {
- return type;
- }
-
- public long getData() {
- return data;
- }
-
- public long getEventId() {
- return eventId;
- }
-
- public int getAggregate() {
- return aggregate;
- }
-
- @JsonIgnore
- @Override
- public Event toEvent() {
- return new OtherEvent(
- EventId.fromSerialized(eventId),
- TestAggregateId.testId(aggregate),
- data);
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java
deleted file mode 100644
index deb9a02..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra.dto;
-
-import org.apache.james.eventsourcing.Event;
-import org.testcontainers.shaded.com.google.common.base.Preconditions;
-
-public class OtherTestEventDTOModule implements EventDTOModule {
-
- public static final String OTHER_TYPE = "other-type";
-
- @Override
- public String getType() {
- return OTHER_TYPE;
- }
-
- @Override
- public Class<? extends EventDTO> getDTOClass() {
- return OtherTestEventDTO.class;
- }
-
- @Override
- public Class<? extends Event> getEventClass() {
- return OtherEvent.class;
- }
-
- @Override
- public EventDTO toDTO(Event event) {
- Preconditions.checkArgument(event instanceof OtherEvent);
- OtherEvent otherEvent = (OtherEvent) event;
-
- return new OtherTestEventDTO(
- OTHER_TYPE,
- otherEvent.getPayload(),
- otherEvent.eventId().serialize(),
- otherEvent.getAggregateId().getId());
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java
deleted file mode 100644
index 529d8a9..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra.dto;
-
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.EventId;
-import org.apache.james.eventsourcing.TestAggregateId;
-import org.apache.james.eventsourcing.TestEvent;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class TestEventDTO implements EventDTO {
- private final String type;
- private final String data;
- private final int eventId;
- private final int aggregate;
-
- @JsonCreator
- public TestEventDTO(
- @JsonProperty("type") String type,
- @JsonProperty("data") String data,
- @JsonProperty("eventId") int eventId,
- @JsonProperty("aggregate") int aggregate) {
- this.type = type;
- this.data = data;
- this.eventId = eventId;
- this.aggregate = aggregate;
- }
-
- public String getType() {
- return type;
- }
-
- public String getData() {
- return data;
- }
-
- public long getEventId() {
- return eventId;
- }
-
- public int getAggregate() {
- return aggregate;
- }
-
- @JsonIgnore
- @Override
- public Event toEvent() {
- return new TestEvent(
- EventId.fromSerialized(eventId),
- TestAggregateId.testId(aggregate),
- data);
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java
deleted file mode 100644
index 6b46268..0000000
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing.cassandra.dto;
-
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.TestEvent;
-import org.testcontainers.shaded.com.google.common.base.Preconditions;
-
-public class TestEventDTOModule implements EventDTOModule {
-
- public static final String TEST_TYPE = "TestType";
-
- @Override
- public String getType() {
- return TEST_TYPE;
- }
-
- @Override
- public Class<? extends EventDTO> getDTOClass() {
- return TestEventDTO.class;
- }
-
- @Override
- public Class<? extends Event> getEventClass() {
- return TestEvent.class;
- }
-
- @Override
- public EventDTO toDTO(Event event) {
- Preconditions.checkArgument(event instanceof TestEvent);
-
- TestEvent testEvent = (TestEvent) event;
- return new TestEventDTO(
- TEST_TYPE,
- testEvent.getData(),
- testEvent.eventId().serialize(),
- testEvent.getAggregateId().getId());
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
index 2f48a55..ca063d9 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
@@ -28,7 +28,7 @@ import java.time.Instant;
import org.apache.james.core.User;
import org.apache.james.eventsourcing.EventId;
-import org.apache.james.eventsourcing.cassandra.JsonEventSerializer;
+import org.apache.james.eventsourcing.eventstore.cassandra.JsonEventSerializer;
import org.apache.james.mailbox.model.Quota;
import org.apache.james.mailbox.quota.QuotaCount;
import org.apache.james.mailbox.quota.QuotaSize;
@@ -46,24 +46,24 @@ import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
class DTOTest {
- public static final Quota<QuotaSize> SIZE_QUOTA = Quota.<QuotaSize>builder().used(QuotaSize.size(23)).computedLimit(QuotaSize.size(33)).build();
- public static final Quota<QuotaCount> COUNT_QUOTA = Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.count(45)).build();
- public static final Instant INSTANT = Instant.ofEpochMilli(45554);
- public static final QuotaThresholdChangedEvent EVENT = new QuotaThresholdChangedEvent(
+ static final Quota<QuotaSize> SIZE_QUOTA = Quota.<QuotaSize>builder().used(QuotaSize.size(23)).computedLimit(QuotaSize.size(33)).build();
+ static final Quota<QuotaCount> COUNT_QUOTA = Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.count(45)).build();
+ static final Instant INSTANT = Instant.ofEpochMilli(45554);
+ static final QuotaThresholdChangedEvent EVENT = new QuotaThresholdChangedEvent(
EventId.first(),
HistoryEvolution.noChanges(),
HistoryEvolution.noChanges(),
SIZE_QUOTA,
COUNT_QUOTA,
UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
- public static final QuotaThresholdChangedEvent EVENT_2 = new QuotaThresholdChangedEvent(
+ static final QuotaThresholdChangedEvent EVENT_2 = new QuotaThresholdChangedEvent(
EventId.first(),
HistoryEvolution.lowerThresholdReached(new QuotaThresholdChange(_75, INSTANT)),
HistoryEvolution.noChanges(),
SIZE_QUOTA,
Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.unlimited()).build(),
UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
- public static final QuotaThresholdChangedEvent EVENT_3 = new QuotaThresholdChangedEvent(
+ static final QuotaThresholdChangedEvent EVENT_3 = new QuotaThresholdChangedEvent(
EventId.first(),
HistoryEvolution.lowerThresholdReached(new QuotaThresholdChange(_75, INSTANT)),
HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_80, INSTANT),
@@ -71,7 +71,7 @@ class DTOTest {
SIZE_QUOTA,
Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.unlimited()).build(),
UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
- public static final QuotaThresholdChangedEvent EVENT_4 = new QuotaThresholdChangedEvent(
+ static final QuotaThresholdChangedEvent EVENT_4 = new QuotaThresholdChangedEvent(
EventId.first(),
HistoryEvolution.lowerThresholdReached(new QuotaThresholdChange(_75, INSTANT)),
HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_80, INSTANT),
@@ -80,24 +80,24 @@ class DTOTest {
Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.unlimited()).build(),
UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
- public static final String EVENT_JSON = ClassLoaderUtils.getSystemResourceAsString("json/event.json");
- public static final String EVENT_JSON_2 = ClassLoaderUtils.getSystemResourceAsString("json/event2.json");
- public static final String EVENT_JSON_3 = ClassLoaderUtils.getSystemResourceAsString("json/event3.json");
- public static final String EVENT_JSON_4 = ClassLoaderUtils.getSystemResourceAsString("json/event4.json");
+ static final String EVENT_JSON = ClassLoaderUtils.getSystemResourceAsString("json/event.json");
+ static final String EVENT_JSON_2 = ClassLoaderUtils.getSystemResourceAsString("json/event2.json");
+ static final String EVENT_JSON_3 = ClassLoaderUtils.getSystemResourceAsString("json/event3.json");
+ static final String EVENT_JSON_4 = ClassLoaderUtils.getSystemResourceAsString("json/event4.json");
- public static final String COUNT_QUOTA_JSON = "{" +
+ static final String COUNT_QUOTA_JSON = "{" +
" \"used\": 12," +
" \"limit\": 45" +
" }";
- public static final String NO_CHANGES_JSON = "{" +
+ static final String NO_CHANGES_JSON = "{" +
" \"change\":\"NoChange\"" +
"}";
private ObjectMapper objectMapper;
@BeforeEach
- public void setUp() {
+ void setUp() {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jdk8Module());
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraEventStoreExtension.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraEventStoreExtension.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraEventStoreExtension.java
new file mode 100644
index 0000000..f46a605
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraEventStoreExtension.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mailbox.quota.cassandra.listeners;
+
+import org.apache.james.eventsourcing.eventstore.cassandra.CassandraGenericEventStoreExtension;
+import org.apache.james.mailbox.quota.cassandra.dto.QuotaThresholdChangedEventDTOModule;
+
+import com.google.common.collect.ImmutableSet;
+
+public class CassandraEventStoreExtension extends CassandraGenericEventStoreExtension {
+ public CassandraEventStoreExtension() {
+ super(ImmutableSet.of(
+ new QuotaThresholdChangedEventDTOModule()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
index 3ea097a..7835898 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
@@ -19,7 +19,6 @@
package org.apache.james.mailbox.quota.cassandra.listeners;
-import org.apache.james.eventsourcing.cassandra.CassandraEventStoreExtension;
import org.apache.james.mailbox.quota.mailing.listeners.QuotaThresholdMailingIntegrationTest;
import org.junit.jupiter.api.extension.ExtendWith;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-memory/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/pom.xml b/mailbox/plugin/quota-mailing-memory/pom.xml
index ad3a70f..aa28165 100644
--- a/mailbox/plugin/quota-mailing-memory/pom.xml
+++ b/mailbox/plugin/quota-mailing-memory/pom.xml
@@ -36,6 +36,27 @@
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
<artifactId>apache-james-mailbox-api</artifactId>
<type>test-jar</type>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java b/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java
deleted file mode 100644
index 11c8e46..0000000
--- a/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsource;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.james.eventsourcing.AggregateId;
-import org.apache.james.eventsourcing.Event;
-import org.apache.james.eventsourcing.EventStore;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-public class InMemoryEventStore implements EventStore {
-
- private final ConcurrentHashMap<AggregateId, History> store;
-
- public InMemoryEventStore() {
- this.store = new ConcurrentHashMap<>();
- }
-
- @Override
- public void appendAll(List<Event> events) {
- if (events.isEmpty()) {
- return;
- }
- AggregateId aggregateId = getAggregateId(events);
-
- if (!store.containsKey(aggregateId)) {
- appendToEmptyHistory(aggregateId, events);
- } else {
- appendToExistingHistory(aggregateId, events);
- }
- }
-
- private AggregateId getAggregateId(List<? extends Event> events) {
- Preconditions.checkArgument(!events.isEmpty());
- Preconditions.checkArgument(Event.belongsToSameAggregate(events));
-
- return events.stream()
- .map(Event::getAggregateId)
- .findFirst()
- .get();
- }
-
- private void appendToEmptyHistory(AggregateId aggregateId, List<Event> events) {
- History newHistory = History.of(events);
-
- History previousHistory = store.putIfAbsent(aggregateId, newHistory);
- if (previousHistory != null) {
- throw new EventStore.EventStoreFailedException();
- }
- }
-
- private void appendToExistingHistory(AggregateId aggregateId, List<? extends Event> events) {
- History currentHistory = store.get(aggregateId);
- List<Event> updatedEvents = updatedEvents(currentHistory, events);
- History updatedHistory = History.of(updatedEvents);
-
- boolean isReplaced = store.replace(aggregateId, currentHistory, updatedHistory);
- if (!isReplaced) {
- throw new EventStore.EventStoreFailedException();
- }
- }
-
- private List<Event> updatedEvents(History currentHistory, List<? extends Event> newEvents) {
- return ImmutableList.<Event>builder()
- .addAll(currentHistory.getEvents())
- .addAll(newEvents)
- .build();
- }
-
- @Override
- public History getEventsOfAggregate(AggregateId aggregateId) {
- return Optional.ofNullable(store.get(aggregateId))
- .orElse(History.empty());
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventSourcingSystemTest.java b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventSourcingSystemTest.java
deleted file mode 100644
index c2f9935..0000000
--- a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventSourcingSystemTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import org.junit.jupiter.api.extension.ExtendWith;
-
-@ExtendWith(InMemoryEventStoreExtension.class)
-public class InMemoryEventSourcingSystemTest implements EventSourcingSystemTest {
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreExtension.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreExtension.java b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreExtension.java
deleted file mode 100644
index c4b345e..0000000
--- a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreExtension.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import org.apache.james.eventsource.InMemoryEventStore;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-
-public class InMemoryEventStoreExtension implements ParameterResolver {
-
- @Override
- public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return (parameterContext.getParameter().getType() == EventStore.class);
- }
-
- @Override
- public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return new InMemoryEventStore();
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreTest.java b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreTest.java
deleted file mode 100644
index eddc2d0..0000000
--- a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/eventsourcing/InMemoryEventStoreTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import org.junit.jupiter.api.extension.ExtendWith;
-
-@ExtendWith(InMemoryEventStoreExtension.class)
-public class InMemoryEventStoreTest implements EventStoreTest {
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaMailingListenersIntegrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaMailingListenersIntegrationTest.java b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaMailingListenersIntegrationTest.java
index 4b17682..1a1ecb2 100644
--- a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaMailingListenersIntegrationTest.java
+++ b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaMailingListenersIntegrationTest.java
@@ -19,7 +19,7 @@
package org.apache.james.mailbox.quota.memory.listeners;
-import org.apache.james.eventsourcing.InMemoryEventStoreExtension;
+import org.apache.james.eventsourcing.eventstore.memory.InMemoryEventStoreExtension;
import org.apache.james.mailbox.quota.mailing.listeners.QuotaThresholdMailingIntegrationTest;
import org.junit.jupiter.api.extension.ExtendWith;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java
index ba65405..409e726 100644
--- a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java
+++ b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java
@@ -19,7 +19,7 @@
package org.apache.james.mailbox.quota.memory.listeners;
-import org.apache.james.eventsourcing.InMemoryEventStoreExtension;
+import org.apache.james.eventsourcing.eventstore.memory.InMemoryEventStoreExtension;
import org.apache.james.mailbox.quota.mailing.listeners.QuotaThresholdConfigurationChangesTest;
import org.junit.jupiter.api.extension.ExtendWith;
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/pom.xml b/mailbox/plugin/quota-mailing/pom.xml
index 8f45fb1..b10bd8e 100644
--- a/mailbox/plugin/quota-mailing/pom.xml
+++ b/mailbox/plugin/quota-mailing/pom.xml
@@ -36,6 +36,20 @@
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
<artifactId>apache-james-mailbox-api</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/AggregateId.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/AggregateId.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/AggregateId.java
deleted file mode 100644
index 18c6224..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/AggregateId.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-public interface AggregateId {
- String asAggregateKey();
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java
deleted file mode 100644
index de8b63f..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/CommandDispatcher.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Supplier;
-import java.util.stream.IntStream;
-
-import javax.inject.Inject;
-
-import com.github.steveash.guavate.Guavate;
-
-public class CommandDispatcher {
-
- private static final int MAX_RETRY = 10;
-
- public interface Command {
- }
-
- public class UnknownCommandException extends RuntimeException {
- private final Command command;
-
- public UnknownCommandException(Command command) {
- super(String.format("Unknown command %s", command));
- this.command = command;
- }
-
- public Command getCommand() {
- return command;
- }
- }
-
- public class TooManyRetries extends RuntimeException {
- private final Command command;
- private final int retries;
-
-
- public TooManyRetries(Command command, int retries) {
- super(String.format("Too much retries for command %s. Store failure after %d retries", command, retries));
- this.command = command;
- this.retries = retries;
- }
-
-
- public Command getCommand() {
- return command;
- }
-
- public int getRetries() {
- return retries;
- }
- }
-
- public interface CommandHandler<C extends Command> {
- Class<C> handledClass();
-
- List<? extends Event> handle(C c);
- }
-
- private final EventBus eventBus;
- @SuppressWarnings("rawtypes")
- private final Map<Class, CommandHandler> handlers;
-
- @Inject
- public CommandDispatcher(EventBus eventBus, Collection<CommandHandler<?>> handlers) {
- this.eventBus = eventBus;
- this.handlers = handlers.stream()
- .collect(Guavate.toImmutableMap(CommandHandler::handledClass, handler -> handler));
- }
-
- public void dispatch(Command c) {
- trySeveralTimes(() -> tryDispatch(c))
- .orElseThrow(() -> new TooManyRetries(c, MAX_RETRY));
- }
-
- public Optional<Integer> trySeveralTimes(Supplier<Boolean> singleTry) {
- return IntStream.range(0, MAX_RETRY)
- .boxed()
- .filter(any -> singleTry.get())
- .findFirst();
- }
-
- @SuppressWarnings("unchecked")
- private boolean tryDispatch(Command c) {
- try {
- List<Event> events =
- Optional.ofNullable(handlers.get(c.getClass()))
- .map(f -> f.handle(c))
- .orElseThrow(() -> new UnknownCommandException(c));
-
- eventBus.publish(events);
- return true;
- } catch (EventStore.EventStoreFailedException e) {
- return false;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java
deleted file mode 100644
index 2b31374..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.List;
-
-public interface Event extends Comparable<Event> {
-
- static boolean belongsToSameAggregate(List<? extends Event> events) {
- return events.stream()
- .map(Event::getAggregateId)
- .distinct()
- .limit(2)
- .count() == 1;
- }
-
- EventId eventId();
-
- AggregateId getAggregateId();
-
- @Override
- default int compareTo(Event o) {
- return eventId().compareTo(o.eventId());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventBus.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventBus.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventBus.java
deleted file mode 100644
index 067d432..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventBus.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.List;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.commons.lang3.tuple.Pair;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableSet;
-
-public class EventBus {
-
- public static final Logger LOGGER = LoggerFactory.getLogger(EventBus.class);
- private final EventStore eventStore;
- private final Set<Subscriber> subscribers;
-
- @Inject
- public EventBus(EventStore eventStore, Set<Subscriber> subscribers) {
- this.eventStore = eventStore;
- this.subscribers = ImmutableSet.copyOf(subscribers);
- }
-
- public void publish(List<Event> events) throws EventStore.EventStoreFailedException {
- eventStore.appendAll(events);
- events.stream()
- .flatMap(event -> subscribers.stream().map(subscriber -> Pair.of(event, subscriber)))
- .forEach(this::handle);
- }
-
- public void handle(Pair<Event, Subscriber> pair) {
- Subscriber subscriber = pair.getRight();
- Event event = pair.getLeft();
- try {
- subscriber.handle(event);
- } catch (Exception e) {
- LOGGER.error("Error while calling {} for {}", subscriber, event, e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/189490a4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java
deleted file mode 100644
index cb5bd1e..0000000
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.eventsourcing;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-
-public class EventId implements Comparable<EventId> {
-
- public static EventId fromSerialized(int value) {
- return new EventId(value);
- }
-
- public static EventId first() {
- return new EventId(0);
- }
-
- private final int value;
-
- private EventId(int value) {
- Preconditions.checkArgument(value >= 0, "EventId can not be negative");
- this.value = value;
- }
-
- public EventId next() {
- return new EventId(value + 1);
- }
-
- public Optional<EventId> previous() {
- if (value > 0) {
- return Optional.of(new EventId(value - 1));
- }
- return Optional.empty();
- }
-
- @Override
- public int compareTo(EventId o) {
- return Long.compare(value, o.value);
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof EventId) {
- EventId eventId = (EventId) o;
-
- return Objects.equals(this.value, eventId.value);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(value);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("value", value)
- .toString();
- }
-
- public int serialize() {
- return value;
- }
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org