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 bt...@apache.org on 2018/10/02 09:28:39 UTC
[6/9] james-project git commit: JAMES-2544 Implemented an event
sourcing system for validating configuration changes
JAMES-2544 Implemented an event sourcing system for validating configuration changes
Temporarily use in memory event store. DTO will be added later on.
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/032c08f0
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/032c08f0
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/032c08f0
Branch: refs/heads/master
Commit: 032c08f08e940a455b209f865a5ee544b507b892
Parents: c147286
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Sep 27 11:16:24 2018 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Oct 2 10:18:32 2018 +0700
----------------------------------------------------------------------
server/queue/queue-rabbitmq/pom.xml | 9 +
.../configuration/ConfigurationAggregate.java | 96 +++++++
.../configuration/ConfigurationChanged.java | 59 +++++
.../EventsourcingConfigurationManagement.java | 65 +++++
.../RegisterConfigurationCommand.java | 64 +++++
.../RegisterConfigurationCommandHandler.java | 47 ++++
...ventsourcingConfigurationManagementTest.java | 247 +++++++++++++++++++
.../RegisterConfigurationCommandTest.java | 55 +++++
8 files changed, 642 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/pom.xml
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/pom.xml b/server/queue/queue-rabbitmq/pom.xml
index 47b958b..b0fdc90 100644
--- a/server/queue/queue-rabbitmq/pom.xml
+++ b/server/queue/queue-rabbitmq/pom.xml
@@ -68,6 +68,15 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>event-sourcing-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>james-server-core</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationAggregate.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationAggregate.java b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationAggregate.java
new file mode 100644
index 0000000..ffa3106
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationAggregate.java
@@ -0,0 +1,96 @@
+/****************************************************************
+ * 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.queue.rabbitmq.view.cassandra.configuration;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.History;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+class ConfigurationAggregate {
+
+ private static class State {
+
+ private static State initial() {
+ return new State(Optional.empty());
+ }
+
+ private Optional<CassandraMailQueueViewConfiguration> maybeConfiguration;
+
+ State(Optional<CassandraMailQueueViewConfiguration> maybeConfiguration) {
+ Preconditions.checkNotNull(maybeConfiguration);
+ this.maybeConfiguration = maybeConfiguration;
+ }
+
+ State set(CassandraMailQueueViewConfiguration configuration) {
+ return new State(Optional.of(configuration));
+ }
+
+ }
+
+ static ConfigurationAggregate load(AggregateId aggregateId, History history) {
+ return new ConfigurationAggregate(aggregateId, history);
+ }
+
+ private static final List<? extends Event> EMPTY_EVENTS = ImmutableList.of();
+
+ private final AggregateId aggregateId;
+ private final History history;
+ private State state;
+
+ ConfigurationAggregate(AggregateId aggregateId, History history) {
+ this.aggregateId = aggregateId;
+ this.history = history;
+ this.state = State.initial();
+
+ history.getEvents().forEach(this::apply);
+ }
+
+ List<? extends Event> registerConfiguration(CassandraMailQueueViewConfiguration configuration) {
+ boolean isSame = state.maybeConfiguration.map(configuration::equals).orElse(false);
+ if (isSame) {
+ return EMPTY_EVENTS;
+ }
+
+ state.maybeConfiguration.ifPresent(oldConfiguration -> oldConfiguration.validateConfigurationChange(configuration));
+
+ return ImmutableList.of(new ConfigurationChanged(
+ aggregateId,
+ history.getNextEventId(),
+ configuration));
+ }
+
+ Optional<CassandraMailQueueViewConfiguration> getCurrentConfiguration() {
+ return state.maybeConfiguration;
+ }
+
+ private void apply(Event event) {
+ if (event instanceof ConfigurationChanged) {
+ ConfigurationChanged configurationChanged = (ConfigurationChanged) event;
+
+ state = state.set(configurationChanged.getConfiguration());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationChanged.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationChanged.java b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationChanged.java
new file mode 100644
index 0000000..7eb984b
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/ConfigurationChanged.java
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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.queue.rabbitmq.view.cassandra.configuration;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+
+import com.google.common.base.Preconditions;
+
+class ConfigurationChanged implements Event {
+
+ private final EventId eventId;
+ private final AggregateId aggregateId;
+ private final CassandraMailQueueViewConfiguration configuration;
+
+ ConfigurationChanged(AggregateId aggregateId,
+ EventId eventId,
+ CassandraMailQueueViewConfiguration configuration) {
+ Preconditions.checkNotNull(aggregateId);
+ Preconditions.checkNotNull(eventId);
+ Preconditions.checkNotNull(configuration);
+
+ this.aggregateId = aggregateId;
+ this.eventId = eventId;
+ this.configuration = configuration;
+ }
+
+ CassandraMailQueueViewConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ @Override
+ public EventId eventId() {
+ return eventId;
+ }
+
+ @Override
+ public AggregateId getAggregateId() {
+ return aggregateId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagement.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagement.java b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagement.java
new file mode 100644
index 0000000..d3a9c5b
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagement.java
@@ -0,0 +1,65 @@
+/****************************************************************
+ * 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.queue.rabbitmq.view.cassandra.configuration;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.EventSourcingSystem;
+import org.apache.james.eventsourcing.Subscriber;
+import org.apache.james.eventsourcing.eventstore.EventStore;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+
+public class EventsourcingConfigurationManagement {
+ static final String CONFIGURATION_AGGREGATE_KEY = "CassandraMailQueueViewConfiguration";
+ static final AggregateId CONFIGURATION_AGGREGATE_ID = () -> CONFIGURATION_AGGREGATE_KEY;
+
+ private static final ImmutableSet<Subscriber> NO_SUBSCRIBER = ImmutableSet.of();
+
+ private final EventStore eventStore;
+ private final EventSourcingSystem eventSourcingSystem;
+
+ @Inject
+ public EventsourcingConfigurationManagement(EventStore eventStore) {
+ this.eventSourcingSystem = new EventSourcingSystem(
+ ImmutableSet.of(new RegisterConfigurationCommandHandler(eventStore)),
+ NO_SUBSCRIBER,
+ eventStore);
+ this.eventStore = eventStore;
+ }
+
+ @VisibleForTesting
+ Optional<CassandraMailQueueViewConfiguration> load() {
+ return ConfigurationAggregate
+ .load(CONFIGURATION_AGGREGATE_ID, eventStore.getEventsOfAggregate(CONFIGURATION_AGGREGATE_ID))
+ .getCurrentConfiguration();
+ }
+
+ public void registerConfiguration(CassandraMailQueueViewConfiguration newConfiguration) {
+ Preconditions.checkNotNull(newConfiguration);
+
+ eventSourcingSystem.dispatch(new RegisterConfigurationCommand(newConfiguration, CONFIGURATION_AGGREGATE_ID));
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommand.java b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommand.java
new file mode 100644
index 0000000..e35bb35
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommand.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.queue.rabbitmq.view.cassandra.configuration;
+
+import java.util.Objects;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Command;
+
+import com.google.common.base.Preconditions;
+
+class RegisterConfigurationCommand implements Command {
+
+ private final CassandraMailQueueViewConfiguration configuration;
+ private final AggregateId aggregateId;
+
+ RegisterConfigurationCommand(CassandraMailQueueViewConfiguration configuration, AggregateId aggregateId) {
+ Preconditions.checkNotNull(configuration);
+ Preconditions.checkNotNull(aggregateId);
+ this.aggregateId = aggregateId;
+ this.configuration = configuration;
+ }
+
+ CassandraMailQueueViewConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof RegisterConfigurationCommand) {
+ RegisterConfigurationCommand that = (RegisterConfigurationCommand) o;
+
+ return Objects.equals(this.configuration, that.configuration)
+ && Objects.equals(this.aggregateId, that.aggregateId);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(configuration, aggregateId);
+ }
+
+ public AggregateId getAggregateId() {
+ return aggregateId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandHandler.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandHandler.java b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandHandler.java
new file mode 100644
index 0000000..a679823
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandHandler.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.queue.rabbitmq.view.cassandra.configuration;
+
+import java.util.List;
+
+import org.apache.james.eventsourcing.CommandHandler;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.EventStore;
+
+class RegisterConfigurationCommandHandler implements CommandHandler<RegisterConfigurationCommand> {
+
+ private final EventStore eventStore;
+
+ RegisterConfigurationCommandHandler(EventStore eventStore) {
+ this.eventStore = eventStore;
+ }
+
+ @Override
+ public Class<RegisterConfigurationCommand> handledClass() {
+ return RegisterConfigurationCommand.class;
+ }
+
+ @Override
+ public List<? extends Event> handle(RegisterConfigurationCommand command) {
+ return ConfigurationAggregate
+ .load(command.getAggregateId(), eventStore.getEventsOfAggregate(command.getAggregateId()))
+ .registerConfiguration(command.getConfiguration());
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java
new file mode 100644
index 0000000..fd5a272
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/EventsourcingConfigurationManagementTest.java
@@ -0,0 +1,247 @@
+/****************************************************************
+ * 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.queue.rabbitmq.view.cassandra.configuration;
+
+import static org.apache.james.queue.rabbitmq.view.cassandra.configuration.EventsourcingConfigurationManagement.CONFIGURATION_AGGREGATE_ID;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.time.Duration;
+import java.util.List;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.eventstore.memory.InMemoryEventStore;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class EventsourcingConfigurationManagementTest {
+ private static final int DEFAULT_BUCKET_COUNT = 10;
+ private static final int DEFAULT_UPDATE_PACE = 100;
+ private static final Duration ONE_HOUR = Duration.ofHours(1);
+ private static final Duration TWO_HOURS = Duration.ofHours(2);
+ private static final Duration FORTY_FIVE_MINUTES = Duration.ofMinutes(45);
+ private static final Duration THIRTY_MINUTES = Duration.ofMinutes(30);
+
+ private static final CassandraMailQueueViewConfiguration FIRST_CONFIGURATION = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build();
+ private static final CassandraMailQueueViewConfiguration SECOND_CONFIGURATION = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT + 1)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build();
+ private static final CassandraMailQueueViewConfiguration THIRD_CONFIGURATION = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT + 2)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build();
+ private InMemoryEventStore eventStore;
+
+ private EventsourcingConfigurationManagement createConfigurationManagement() {
+ return new EventsourcingConfigurationManagement(eventStore);
+ }
+
+ @BeforeEach
+ void setUp() {
+ eventStore = new InMemoryEventStore();
+ }
+
+ @Test
+ void loadShouldReturnEmptyIfNoConfigurationStored() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+
+ assertThat(testee.load())
+ .isEmpty();
+ }
+
+ @Test
+ void loadShouldReturnTheLastConfiguration() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(FIRST_CONFIGURATION);
+ testee.registerConfiguration(SECOND_CONFIGURATION);
+ testee.registerConfiguration(THIRD_CONFIGURATION);
+
+ assertThat(testee.load())
+ .contains(THIRD_CONFIGURATION);
+ }
+
+ @Test
+ void loadConfigurationShouldThrowWhenConfigurationIsNull() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+
+ assertThatThrownBy(() -> testee.registerConfiguration(null))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ void loadConfigurationShouldThrowWhenBucketCountDecrease() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build());
+
+ assertThatThrownBy(() -> testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT - 1)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build()))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void loadConfigurationShouldUpdateStoredConfigurationWhenIncreaseBucketCount() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build());
+
+ CassandraMailQueueViewConfiguration increaseOneBucketConfiguration = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT + 1)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build();
+ testee.registerConfiguration(increaseOneBucketConfiguration);
+
+ assertThat(testee.load())
+ .contains(increaseOneBucketConfiguration);
+ }
+
+ @Test
+ void loadConfigurationShouldStoreConfiguration() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+
+ testee.registerConfiguration(FIRST_CONFIGURATION);
+
+ assertThat(testee.load())
+ .contains(FIRST_CONFIGURATION);
+ }
+
+ @Test
+ void loadConfigurationShouldThrowWhenIncreaseSliceWindow() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build());
+
+ assertThatThrownBy(() -> testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(TWO_HOURS)
+ .build()))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void loadConfigurationShouldThrowWhenDecreaseSliceWindowByANotDivisibleNumber() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build());
+
+ assertThatThrownBy(() -> testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(FORTY_FIVE_MINUTES)
+ .build()))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void loadConfigurationShouldUpdateConfigurationWhenDecreaseSliceWindowByADivisibleNumber() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build());
+
+ CassandraMailQueueViewConfiguration decreaseTwiceSliceWindowConfiguration = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(THIRTY_MINUTES)
+ .build();
+ testee.registerConfiguration(decreaseTwiceSliceWindowConfiguration);
+
+ assertThat(testee.load())
+ .contains(decreaseTwiceSliceWindowConfiguration);
+ }
+
+ @Test
+ void loadConfigurationShouldUpdateConfigurationWhenIncreaseUpdatePace() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build());
+
+ CassandraMailQueueViewConfiguration decreaseTwiceSliceWindowConfiguration = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE + 10)
+ .sliceWindow(ONE_HOUR)
+ .build();
+ testee.registerConfiguration(decreaseTwiceSliceWindowConfiguration);
+
+ assertThat(testee.load())
+ .contains(decreaseTwiceSliceWindowConfiguration);
+ }
+
+ @Test
+ void loadConfigurationShouldUpdateConfigurationWhenDecreaseUpdatePace() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE)
+ .sliceWindow(ONE_HOUR)
+ .build());
+
+ CassandraMailQueueViewConfiguration decreaseTwiceSliceWindowConfiguration = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(DEFAULT_BUCKET_COUNT)
+ .updateBrowseStartPace(DEFAULT_UPDATE_PACE - 10)
+ .sliceWindow(ONE_HOUR)
+ .build();
+ testee.registerConfiguration(decreaseTwiceSliceWindowConfiguration);
+
+ assertThat(testee.load())
+ .contains(decreaseTwiceSliceWindowConfiguration);
+ }
+
+ @Test
+ void loadConfigurationShouldIgnoreDuplicateWhenStoreTheSameConfigurationTwice() {
+ EventsourcingConfigurationManagement testee = createConfigurationManagement();
+ testee.registerConfiguration(FIRST_CONFIGURATION);
+ testee.registerConfiguration(FIRST_CONFIGURATION);
+
+ List<Event> eventsStored = eventStore.getEventsOfAggregate(CONFIGURATION_AGGREGATE_ID)
+ .getEvents();
+ assertThat(eventsStored)
+ .hasSize(1);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/032c08f0/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandTest.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandTest.java b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandTest.java
new file mode 100644
index 0000000..c845413
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/cassandra/configuration/RegisterConfigurationCommandTest.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.queue.rabbitmq.view.cassandra.configuration;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.time.Duration;
+
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class RegisterConfigurationCommandTest {
+
+ @Test
+ void shouldMatchBeanContract() {
+ EqualsVerifier.forClass(RegisterConfigurationCommand.class)
+ .verify();
+ }
+
+ @Test
+ void constructorShouldThrowWhenNullConfiguration() {
+ assertThatThrownBy(() -> new RegisterConfigurationCommand(null, () -> "agg"))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ void constructorShouldThrowWhenNullAggregateId() {
+ CassandraMailQueueViewConfiguration configuration = CassandraMailQueueViewConfiguration.builder()
+ .bucketCount(2)
+ .updateBrowseStartPace(1000)
+ .sliceWindow(Duration.ofHours(1))
+ .build();
+
+ assertThatThrownBy(() -> new RegisterConfigurationCommand(configuration, null))
+ .isInstanceOf(NullPointerException.class);
+ }
+}
\ 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