This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 970355457d2cd6cea900a7feda802cec80dd98f8 Author: Benoit Tellier <[email protected]> AuthorDate: Tue Dec 17 16:34:42 2019 +0700 JAMES-3014 Give a probe for clearing MessageFastViewProjection --- .../apache/james/jmap/draft/JmapGuiceProbe.java | 11 ++- .../CassandraMessageFastViewProjection.java | 16 +++-- .../api/projections/MessageFastViewProjection.java | 2 + .../MemoryMessageFastViewProjection.java | 15 ++-- .../MessageFastViewProjectionContract.java | 80 +++++++++++++--------- 5 files changed, 83 insertions(+), 41 deletions(-) diff --git a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JmapGuiceProbe.java b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JmapGuiceProbe.java index 38ca47c..0f2504b 100644 --- a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JmapGuiceProbe.java +++ b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JmapGuiceProbe.java @@ -24,6 +24,7 @@ import java.util.Arrays; import javax.inject.Inject; import org.apache.james.core.Username; +import org.apache.james.jmap.api.projections.MessageFastViewProjection; import org.apache.james.jmap.api.vacation.AccountId; import org.apache.james.jmap.api.vacation.Vacation; import org.apache.james.jmap.api.vacation.VacationPatch; @@ -39,6 +40,8 @@ import org.apache.james.mailbox.model.MessageId; import org.apache.james.util.Port; import org.apache.james.utils.GuiceProbe; +import reactor.core.publisher.Mono; + public class JmapGuiceProbe implements GuiceProbe { private final VacationRepository vacationRepository; @@ -46,14 +49,16 @@ public class JmapGuiceProbe implements GuiceProbe { private final MessageIdManager messageIdManager; private final MailboxManager mailboxManager; private final EventBus eventBus; + private final MessageFastViewProjection messageFastViewProjection; @Inject - private JmapGuiceProbe(VacationRepository vacationRepository, JMAPServer jmapServer, MessageIdManager messageIdManager, MailboxManager mailboxManager, EventBus eventBus) { + private JmapGuiceProbe(VacationRepository vacationRepository, JMAPServer jmapServer, MessageIdManager messageIdManager, MailboxManager mailboxManager, EventBus eventBus, MessageFastViewProjection messageFastViewProjection) { this.vacationRepository = vacationRepository; this.jmapServer = jmapServer; this.messageIdManager = messageIdManager; this.mailboxManager = mailboxManager; this.eventBus = eventBus; + this.messageFastViewProjection = messageFastViewProjection; } public Port getJmapPort() { @@ -76,4 +81,8 @@ public class JmapGuiceProbe implements GuiceProbe { MailboxSession mailboxSession = mailboxManager.createSystemSession(username); messageIdManager.setInMailboxes(messageId, Arrays.asList(mailboxIds), mailboxSession); } + + public void clearMessageFastViewProjection() { + Mono.from(messageFastViewProjection.clear()).block(); + } } diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraMessageFastViewProjection.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraMessageFastViewProjection.java index 9b0ac29..628a3b6 100644 --- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraMessageFastViewProjection.java +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraMessageFastViewProjection.java @@ -23,6 +23,7 @@ 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 com.datastax.driver.core.querybuilder.QueryBuilder.truncate; import static org.apache.james.jmap.cassandra.projections.table.CassandraMessageFastViewProjectionTable.HAS_ATTACHMENT; import static org.apache.james.jmap.cassandra.projections.table.CassandraMessageFastViewProjectionTable.MESSAGE_ID; import static org.apache.james.jmap.cassandra.projections.table.CassandraMessageFastViewProjectionTable.PREVIEW; @@ -38,7 +39,6 @@ import org.apache.james.mailbox.cassandra.ids.CassandraMessageId; import org.apache.james.mailbox.model.MessageId; import org.apache.james.metrics.api.Metric; import org.apache.james.metrics.api.MetricFactory; -import org.reactivestreams.Publisher; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.Row; @@ -58,6 +58,7 @@ public class CassandraMessageFastViewProjection implements MessageFastViewProjec private final PreparedStatement storeStatement; private final PreparedStatement retrieveStatement; private final PreparedStatement deleteStatement; + private final PreparedStatement truncateStatement; @Inject CassandraMessageFastViewProjection(MetricFactory metricFactory, Session session) { @@ -76,12 +77,14 @@ public class CassandraMessageFastViewProjection implements MessageFastViewProjec .from(TABLE_NAME) .where(eq(MESSAGE_ID, bindMarker(MESSAGE_ID)))); + this.truncateStatement = session.prepare(truncate(TABLE_NAME)); + this.metricRetrieveHitCount = metricFactory.generate(METRIC_RETRIEVE_HIT_COUNT); this.metricRetrieveMissCount = metricFactory.generate(METRIC_RETRIEVE_MISS_COUNT); } @Override - public Publisher<Void> store(MessageId messageId, MessageFastViewPrecomputedProperties precomputedProperties) { + public Mono<Void> store(MessageId messageId, MessageFastViewPrecomputedProperties precomputedProperties) { checkMessage(messageId); return cassandraAsyncExecutor.executeVoid(storeStatement.bind() @@ -91,7 +94,7 @@ public class CassandraMessageFastViewProjection implements MessageFastViewProjec } @Override - public Publisher<MessageFastViewPrecomputedProperties> retrieve(MessageId messageId) { + public Mono<MessageFastViewPrecomputedProperties> retrieve(MessageId messageId) { checkMessage(messageId); return cassandraAsyncExecutor.executeSingleRow(retrieveStatement.bind() @@ -102,13 +105,18 @@ public class CassandraMessageFastViewProjection implements MessageFastViewProjec } @Override - public Publisher<Void> delete(MessageId messageId) { + public Mono<Void> delete(MessageId messageId) { checkMessage(messageId); return cassandraAsyncExecutor.executeVoid(deleteStatement.bind() .setUUID(MESSAGE_ID, ((CassandraMessageId) messageId).get())); } + @Override + public Mono<Void> clear() { + return cassandraAsyncExecutor.executeVoid(truncateStatement.bind()); + } + private void checkMessage(MessageId messageId) { Preconditions.checkNotNull(messageId); Preconditions.checkArgument(messageId instanceof CassandraMessageId, diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewProjection.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewProjection.java index 6589318..afc3e15 100644 --- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewProjection.java +++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewProjection.java @@ -44,6 +44,8 @@ public interface MessageFastViewProjection { Publisher<Void> delete(MessageId messageId); + Publisher<Void> clear(); + default Publisher<Map<MessageId, MessageFastViewPrecomputedProperties>> retrieve(Collection<MessageId> messageIds) { Preconditions.checkNotNull(messageIds); diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryMessageFastViewProjection.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryMessageFastViewProjection.java index e39fcbe..928bc5b 100644 --- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryMessageFastViewProjection.java +++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryMessageFastViewProjection.java @@ -35,13 +35,13 @@ import reactor.core.publisher.Mono; public class MemoryMessageFastViewProjection implements MessageFastViewProjection { - private final ConcurrentHashMap<MessageId, MessageFastViewPrecomputedProperties> previews; + private final ConcurrentHashMap<MessageId, MessageFastViewPrecomputedProperties> projectionItems; private final Metric metricRetrieveHitCount; private final Metric metricRetrieveMissCount; @Inject public MemoryMessageFastViewProjection(MetricFactory metricFactory) { - this.previews = new ConcurrentHashMap<>(); + this.projectionItems = new ConcurrentHashMap<>(); this.metricRetrieveHitCount = metricFactory.generate(METRIC_RETRIEVE_HIT_COUNT); this.metricRetrieveMissCount = metricFactory.generate(METRIC_RETRIEVE_MISS_COUNT); } @@ -51,14 +51,14 @@ public class MemoryMessageFastViewProjection implements MessageFastViewProjectio Preconditions.checkNotNull(messageId); Preconditions.checkNotNull(precomputedProperties); - return Mono.fromRunnable(() -> previews.put(messageId, precomputedProperties)); + return Mono.fromRunnable(() -> projectionItems.put(messageId, precomputedProperties)); } @Override public Mono<MessageFastViewPrecomputedProperties> retrieve(MessageId messageId) { Preconditions.checkNotNull(messageId); - return Mono.fromSupplier(() -> previews.get(messageId)) + return Mono.fromSupplier(() -> projectionItems.get(messageId)) .doOnNext(preview -> metricRetrieveHitCount.increment()) .switchIfEmpty(Mono.fromRunnable(metricRetrieveMissCount::increment)); } @@ -67,6 +67,11 @@ public class MemoryMessageFastViewProjection implements MessageFastViewProjectio public Mono<Void> delete(MessageId messageId) { Preconditions.checkNotNull(messageId); - return Mono.fromRunnable(() -> previews.remove(messageId)); + return Mono.fromRunnable(() -> projectionItems.remove(messageId)); + } + + @Override + public Mono<Void> clear() { + return Mono.fromRunnable(projectionItems::clear); } } diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionContract.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionContract.java index f57ff23..5a6c3e5 100644 --- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionContract.java +++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionContract.java @@ -173,34 +173,34 @@ public interface MessageFastViewProjectionContract { @Test default void storeShouldThrowWhenNullPreview() { - MessageId messageId1 = newMessageId(); - assertThatThrownBy(() -> Mono.from(testee().store(messageId1, null)).block()) + MessageId messageId = newMessageId(); + assertThatThrownBy(() -> Mono.from(testee().store(messageId, null)).block()) .isInstanceOf(NullPointerException.class); } @Test default void storeShouldOverrideOldRecord() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + MessageId messageId = newMessageId(); + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) .block(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_2)) + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_2)) .block(); - assertThat(Mono.from(testee().retrieve(messageId1)).block()) + assertThat(Mono.from(testee().retrieve(messageId)).block()) .isEqualTo(MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_2); } @Test default void storeShouldBeIdempotent() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + MessageId messageId = newMessageId(); + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) .block(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) .block(); - assertThat(Mono.from(testee().retrieve(messageId1)).block()) + assertThat(Mono.from(testee().retrieve(messageId)).block()) .isEqualTo(MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1); } @@ -264,21 +264,21 @@ public interface MessageFastViewProjectionContract { @Test default void deleteShouldNotThrowWhenMessageIdNotFound() { - MessageId messageId1 = newMessageId(); - assertThatCode(() -> Mono.from(testee().delete(messageId1)).block()) + MessageId messageId = newMessageId(); + assertThatCode(() -> Mono.from(testee().delete(messageId)).block()) .doesNotThrowAnyException(); } @Test default void deleteShouldDeleteStoredRecord() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + MessageId messageId = newMessageId(); + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) .block(); - Mono.from(testee().delete(messageId1)) + Mono.from(testee().delete(messageId)) .block(); - assertThat(Mono.from(testee().retrieve(messageId1)).blockOptional()) + assertThat(Mono.from(testee().retrieve(messageId)).blockOptional()) .isEmpty(); } @@ -300,26 +300,26 @@ public interface MessageFastViewProjectionContract { @Test default void deleteShouldBeIdempotent() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + MessageId messageId = newMessageId(); + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) .block(); - Mono.from(testee().delete(messageId1)) + Mono.from(testee().delete(messageId)) .block(); - Mono.from(testee().delete(messageId1)) + Mono.from(testee().delete(messageId)) .block(); - assertThat(Mono.from(testee().retrieve(messageId1)).blockOptional()) + assertThat(Mono.from(testee().retrieve(messageId)).blockOptional()) .isEmpty(); } @Test default void retrieveShouldIncrementMetricHitCountWhenPreviewIsFound() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + MessageId messageId = newMessageId(); + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) .block(); - Mono.from(testee().retrieve(messageId1)) + Mono.from(testee().retrieve(messageId)) .block(); assertThat(metricFactory().countFor(METRIC_RETRIEVE_HIT_COUNT)) @@ -328,11 +328,11 @@ public interface MessageFastViewProjectionContract { @Test default void retrieveShouldNotIncrementMetricMissCountWhenPreviewIsFound() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().store(messageId1, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + MessageId messageId = newMessageId(); + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) .block(); - Mono.from(testee().retrieve(messageId1)) + Mono.from(testee().retrieve(messageId)) .block(); assertThat(metricFactory().countFor(METRIC_RETRIEVE_MISS_COUNT)) @@ -341,8 +341,8 @@ public interface MessageFastViewProjectionContract { @Test default void retrieveShouldIncrementMetricMissCountWhenPreviewIsNotFound() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().retrieve(messageId1)) + MessageId messageId = newMessageId(); + Mono.from(testee().retrieve(messageId)) .block(); assertThat(metricFactory().countFor(METRIC_RETRIEVE_MISS_COUNT)) @@ -351,11 +351,29 @@ public interface MessageFastViewProjectionContract { @Test default void retrieveShouldNotIncrementMetricHitCountWhenPreviewIsNotFound() { - MessageId messageId1 = newMessageId(); - Mono.from(testee().retrieve(messageId1)) + MessageId messageId = newMessageId(); + Mono.from(testee().retrieve(messageId)) .block(); assertThat(metricFactory().countFor(METRIC_RETRIEVE_HIT_COUNT)) .isEqualTo(0); } + + @Test + default void clearShouldNotThrowWhenNoData() { + assertThatCode(() -> Mono.from(testee().clear()).block()) + .doesNotThrowAnyException(); + } + + @Test + default void clearShouldRemoveStoredData() { + MessageId messageId = newMessageId(); + Mono.from(testee().store(messageId, MESSAGE_FAST_VIEW_PRECOMPUTED_PROPERTIES_1)) + .block(); + + Mono.from(testee().clear()).block(); + + assertThat(Mono.from(testee().retrieve(messageId)).blockOptional()) + .isEmpty(); + } } \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
