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 2020/02/27 16:20:23 UTC

[james-project] 02/14: JAMES-3009 convert to scala event-store-api

This is an automated email from the ASF dual-hosted git repository.

matthieu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit b9d6d7713ada5e69b9d43c627955ba5b909514b4
Author: RĂ©mi KOWALSKI <rk...@linagora.com>
AuthorDate: Fri Dec 6 12:20:08 2019 +0100

    JAMES-3009 convert to scala event-store-api
---
 .../eventsourcing/EventSourcingSystemTest.java     |  5 +-
 event-sourcing/event-store-api/pom.xml             | 17 +++-
 .../james/eventsourcing/eventstore/History.java    | 94 ----------------------
 .../eventsourcing/eventstore/EventStore.scala}     | 42 +++++-----
 .../eventstore/EventStoreFailedException.scala}    | 15 ++--
 .../james/eventsourcing/eventstore/History.scala   | 50 ++++++++++++
 .../eventsourcing/eventstore/EventStoreTest.java   |  6 +-
 .../eventsourcing/eventstore/HistoryTest.java      | 20 ++---
 8 files changed, 101 insertions(+), 148 deletions(-)

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
index 13a4ed2..3fe8297 100644
--- 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
@@ -37,6 +37,7 @@ import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import scala.jdk.javaapi.CollectionConverters;
 
 public interface EventSourcingSystemTest {
 
@@ -119,7 +120,7 @@ public interface EventSourcingSystemTest {
         eventSourcingSystem.dispatch(new MyCommand(PAYLOAD_1));
 
         TestEvent expectedEvent = new TestEvent(EventId.first(), AGGREGATE_ID, PAYLOAD_1);
-        assertThat(eventStore.getEventsOfAggregate(AGGREGATE_ID).getEvents())
+        assertThat(CollectionConverters.asJava(eventStore.getEventsOfAggregate(AGGREGATE_ID).getEvents()))
             .containsOnly(expectedEvent);
     }
 
@@ -150,7 +151,7 @@ public interface EventSourcingSystemTest {
 
         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())
+        assertThat(CollectionConverters.asJava(eventStore.getEventsOfAggregate(AGGREGATE_ID).getEvents()))
             .containsOnly(expectedEvent1, expectedEvent2);
     }
 
diff --git a/event-sourcing/event-store-api/pom.xml b/event-sourcing/event-store-api/pom.xml
index 96329bf..30f0231 100644
--- a/event-sourcing/event-store-api/pom.xml
+++ b/event-sourcing/event-store-api/pom.xml
@@ -51,6 +51,21 @@
             <groupId>com.github.steveash.guavate</groupId>
             <artifactId>guavate</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-library</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.scala-lang.modules</groupId>
+            <artifactId>scala-java8-compat_${scala.base}</artifactId>
+        </dependency>
     </dependencies>
-
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>net.alchim31.maven</groupId>
+                <artifactId>scala-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
 </project>
\ No newline at end of file
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
deleted file mode 100644
index 62cc119..0000000
--- a/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/History.java
+++ /dev/null
@@ -1,94 +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.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("Event History contains duplicated EventId");
-        }
-        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);
-    }
-}
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/scala/org/apache/james/eventsourcing/eventstore/EventStore.scala
similarity index 55%
rename from event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStore.java
rename to event-sourcing/event-store-api/src/main/scala/org/apache/james/eventsourcing/eventstore/EventStore.scala
index 3b3a95e..cf1a903 100644
--- a/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStore.java
+++ b/event-sourcing/event-store-api/src/main/scala/org/apache/james/eventsourcing/eventstore/EventStore.scala
@@ -7,7 +7,7 @@
  * "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                 *
+ * 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  *
@@ -15,33 +15,27 @@
  * 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
 
-package org.apache.james.eventsourcing.eventstore;
+import org.apache.james.eventsourcing.{AggregateId, Event}
 
-import java.util.List;
+import scala.annotation.varargs
+import scala.jdk.CollectionConverters._
 
-import org.apache.james.eventsourcing.AggregateId;
-import org.apache.james.eventsourcing.Event;
+trait EventStore {
+  def append(event: Event): Unit = appendAll(List(event))
 
-import com.google.common.collect.ImmutableList;
+  @varargs
+  def appendAll(events: Event*): Unit = appendAll(events.toList)
 
-public interface EventStore {
+  def appendAll(events: java.util.List[Event]): Unit = appendAll(events.asScala.toList)
 
-    default void append(Event event) {
-        appendAll(ImmutableList.of(event));
-    }
+  /**
+   * 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
+   */
+  def appendAll(events: List[Event]) : Unit
 
-    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);
-
-}
+  def getEventsOfAggregate(aggregateId: AggregateId) : History
+}
\ No newline at end of file
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/scala/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.scala
similarity index 71%
rename from event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.java
rename to event-sourcing/event-store-api/src/main/scala/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.scala
index fb94373..2549ea1 100644
--- a/event-sourcing/event-store-api/src/main/java/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.java
+++ b/event-sourcing/event-store-api/src/main/scala/org/apache/james/eventsourcing/eventstore/EventStoreFailedException.scala
@@ -1,4 +1,4 @@
-/****************************************************************
+/** **************************************************************
  * 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        *
@@ -7,7 +7,7 @@
  * "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                 *
+ * 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  *
@@ -15,12 +15,7 @@
  * 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
 
-package org.apache.james.eventsourcing.eventstore;
-
-public class EventStoreFailedException extends RuntimeException {
-    public EventStoreFailedException(String message) {
-        super(message);
-    }
-}
+case class EventStoreFailedException(message: String) extends RuntimeException(message)
\ No newline at end of file
diff --git a/event-sourcing/event-store-api/src/main/scala/org/apache/james/eventsourcing/eventstore/History.scala b/event-sourcing/event-store-api/src/main/scala/org/apache/james/eventsourcing/eventstore/History.scala
new file mode 100644
index 0000000..05c8fb2
--- /dev/null
+++ b/event-sourcing/event-store-api/src/main/scala/org/apache/james/eventsourcing/eventstore/History.scala
@@ -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
+
+import org.apache.james.eventsourcing.{Event, EventId}
+
+import scala.annotation.varargs
+import scala.jdk.CollectionConverters._
+
+object History {
+  def empty: History = new History(Nil)
+
+  def of(events: List[Event]): History = new History(events)
+  def of(events: java.util.List[Event]): History = new History(events.asScala.toList)
+
+  @varargs
+  def of(events: Event*): History = of(events.toList)
+}
+
+case class History private(events: List[Event]) {
+  if (hasEventIdDuplicates(events)) throw EventStoreFailedException("Event History contains duplicated EventId")
+
+  private def hasEventIdDuplicates(events: List[Event]) = {
+    val eventIdsNumber = events.map(event => event.eventId()).toSet.size
+    eventIdsNumber != events.size
+  }
+
+  def getVersion: Option[EventId] = events.map(event => event.eventId()).maxOption
+
+  def getEvents = events
+
+  def getNextEventId: EventId = getVersion.map(eventId => eventId.next).getOrElse(EventId.first)
+
+}
\ No newline at end of file
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
index dc312d9..4638a44 100644
--- 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
@@ -29,8 +29,6 @@ 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);
@@ -72,7 +70,7 @@ public interface EventStoreTest {
         TestEvent event = new TestEvent(EventId.first(), AGGREGATE_1, "first");
         testee.append(event);
         assertThat(testee.getEventsOfAggregate(AGGREGATE_1))
-            .isEqualTo(History.of(ImmutableList.of(event)));
+            .isEqualTo(History.of(event));
     }
 
     @Test
@@ -82,7 +80,7 @@ public interface EventStoreTest {
         testee.append(event1);
         testee.append(event2);
         assertThat(testee.getEventsOfAggregate(AGGREGATE_1))
-            .isEqualTo(History.of(ImmutableList.of(event1, event2)));
+            .isEqualTo(History.of(event1, event2));
     }
 
 }
\ No newline at end of file
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
index db5e79e..98558c7 100644
--- 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
@@ -27,17 +27,11 @@ import org.apache.james.eventsourcing.TestAggregateId;
 import org.apache.james.eventsourcing.TestEvent;
 import org.junit.jupiter.api.Test;
 
-import nl.jqno.equalsverifier.EqualsVerifier;
+import scala.compat.java8.OptionConverters;
 
 class HistoryTest {
 
     @Test
-    void shouldMatchBeanContract() {
-        EqualsVerifier.forClass(History.class)
-            .verify();
-    }
-
-    @Test
     void emptyShouldGenerateAnEmptyHistory() {
         assertThat(History.empty())
             .isEqualTo(History.of());
@@ -45,18 +39,18 @@ class HistoryTest {
 
     @Test
     void getVersionShouldReturnEmptyWhenEmpty() {
-        assertThat(History.empty()
-            .getVersion())
+        assertThat(OptionConverters.toJava(History.empty()
+            .getVersion()))
             .isEmpty();
     }
 
     @Test
     void getVersionShouldReturnSingleEventIdWhenSingleEvent() {
-        assertThat(History
+        assertThat(OptionConverters.toJava(History
             .of(new TestEvent(EventId.first(),
                 TestAggregateId.testId(42),
                 "any"))
-            .getVersion())
+            .getVersion()))
             .contains(EventId.first());
     }
 
@@ -69,8 +63,8 @@ class HistoryTest {
             TestAggregateId.testId(42),
             "any");
 
-        assertThat(History.of(event1, event2)
-            .getVersion())
+        assertThat(OptionConverters.toJava(History.of(event1, event2)
+            .getVersion()))
             .contains(event2.eventId());
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org