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 2020/05/04 03:21:29 UTC

[james-project] 10/12: JAMES-3105 Expose trustMessageDenormalization over webadmin

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 7e873ebef6c542a857fb7d9ed2e35a67d19b0007
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Apr 23 17:36:55 2020 +0700

    JAMES-3105 Expose trustMessageDenormalization over webadmin
    
    `trustMessageDenormalization` query parameter can be set to `true`. This will result in a better performance running the
    task at the cost of safety in the face of message denormalization inconsistencies. Defaults to false, which generates
    additional checks.
---
 .../mail/task/RecomputeMailboxCountersService.java | 15 +++++
 .../task/RecomputeMailboxCountersServiceTest.java  | 18 ++++--
 .../RecomputeMailboxCountersRequestToTask.java     | 32 ++++++++++-
 .../RecomputeMailboxCountersRequestToTaskTest.java | 66 ++++++++++++++++++++++
 src/site/markdown/server/manage-webadmin.md        |  4 ++
 5 files changed, 129 insertions(+), 6 deletions(-)

diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersService.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersService.java
index b39db27..7970a32 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersService.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersService.java
@@ -77,6 +77,21 @@ public class RecomputeMailboxCountersService {
         public boolean isMessageDenormalizationTrusted() {
             return trustMessageDenormalization;
         }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof Options) {
+                Options options = (Options) o;
+
+                return Objects.equals(this.trustMessageDenormalization, options.trustMessageDenormalization);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(trustMessageDenormalization);
+        }
     }
 
     private static class Counter {
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java
index 10382a8..4df80a4 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java
@@ -39,6 +39,7 @@ import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.task.RecomputeMailboxCountersService.Context;
+import org.apache.james.mailbox.cassandra.mail.task.RecomputeMailboxCountersService.Options;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
@@ -56,6 +57,8 @@ import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
+import nl.jqno.equalsverifier.EqualsVerifier;
+
 class RecomputeMailboxCountersServiceTest {
     private static final UidValidity UID_VALIDITY_1 = UidValidity.of(145);
     private static final Username USER = Username.of("user");
@@ -91,6 +94,11 @@ class RecomputeMailboxCountersServiceTest {
         testee = new RecomputeMailboxCountersService(mailboxDAO, imapUidToMessageIdDAO, messageIdToImapUidDAO, counterDAO);
     }
 
+    @Test
+    void optionsShouldMatchBeanContract() {
+        EqualsVerifier.forClass(Options.class).verify();
+    }
+
     @Nested
     class TrustMessageDenormalizationTest implements Contract {
         @Override
@@ -104,8 +112,8 @@ class RecomputeMailboxCountersServiceTest {
         }
 
         @Override
-        public RecomputeMailboxCountersService.Options options() {
-            return RecomputeMailboxCountersService.Options.trustMessageDenormalization();
+        public Options options() {
+            return Options.trustMessageDenormalization();
         }
 
         @Override
@@ -155,8 +163,8 @@ class RecomputeMailboxCountersServiceTest {
         }
 
         @Override
-        public RecomputeMailboxCountersService.Options options() {
-            return RecomputeMailboxCountersService.Options.recheckMessageDenormalization();
+        public Options options() {
+            return Options.recheckMessageDenormalization();
         }
 
         @Override
@@ -180,7 +188,7 @@ class RecomputeMailboxCountersServiceTest {
 
         CassandraMailboxDAO mailboxDAO();
 
-        RecomputeMailboxCountersService.Options options();
+        Options options();
 
         CassandraMessageIdDAO imapUidToMessageIdDAO();
 
diff --git a/server/protocols/webadmin/webadmin-cassandra/src/main/java/org/apache/james/webadmin/routes/RecomputeMailboxCountersRequestToTask.java b/server/protocols/webadmin/webadmin-cassandra/src/main/java/org/apache/james/webadmin/routes/RecomputeMailboxCountersRequestToTask.java
index 2d60e61..a090913 100644
--- a/server/protocols/webadmin/webadmin-cassandra/src/main/java/org/apache/james/webadmin/routes/RecomputeMailboxCountersRequestToTask.java
+++ b/server/protocols/webadmin/webadmin-cassandra/src/main/java/org/apache/james/webadmin/routes/RecomputeMailboxCountersRequestToTask.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.webadmin.routes;
 
+import java.util.Optional;
+
 import javax.inject.Inject;
 
 import org.apache.james.mailbox.cassandra.mail.task.RecomputeMailboxCountersService;
@@ -27,12 +29,40 @@ import org.apache.james.mailbox.cassandra.mail.task.RecomputeMailboxCountersTask
 import org.apache.james.webadmin.tasks.TaskFromRequestRegistry;
 import org.apache.james.webadmin.tasks.TaskRegistrationKey;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+import spark.Request;
+
 public class RecomputeMailboxCountersRequestToTask extends TaskFromRequestRegistry.TaskRegistration {
     private static final TaskRegistrationKey REGISTRATION_KEY = TaskRegistrationKey.of("RecomputeMailboxCounters");
+    public static final String TRUST_PARAM = "trustMessageDenormalization";
 
     @Inject
     public RecomputeMailboxCountersRequestToTask(RecomputeMailboxCountersService service) {
         super(REGISTRATION_KEY,
-            request -> new RecomputeMailboxCountersTask(service, Options.recheckMessageDenormalization()));
+            request -> new RecomputeMailboxCountersTask(service, parseOptions(request)));
+    }
+
+    private static Options parseOptions(Request request) {
+        var stringValue = Optional.ofNullable(request.queryParams(TRUST_PARAM));
+        return parseOptions(stringValue);
+    }
+
+    @VisibleForTesting
+    static Options parseOptions(Optional<String> stringValue) {
+        return stringValue
+            .map(RecomputeMailboxCountersRequestToTask::parseOptions)
+            .orElse(Options.recheckMessageDenormalization());
+    }
+
+    private static Options parseOptions(String stringValue) {
+        Preconditions.checkArgument(isValid(stringValue), "'%s' needs to be a valid boolean", TRUST_PARAM);
+        return Options.of(Boolean.valueOf(stringValue));
+    }
+
+    private static boolean isValid(String stringValue) {
+        return stringValue.equalsIgnoreCase("true")
+            || stringValue.equalsIgnoreCase("false");
     }
 }
diff --git a/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/RecomputeMailboxCountersRequestToTaskTest.java b/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/RecomputeMailboxCountersRequestToTaskTest.java
new file mode 100644
index 0000000..780fb71
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-cassandra/src/test/java/org/apache/james/webadmin/routes/RecomputeMailboxCountersRequestToTaskTest.java
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.webadmin.routes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Optional;
+
+import org.apache.james.mailbox.cassandra.mail.task.RecomputeMailboxCountersService.Options;
+import org.junit.jupiter.api.Test;
+
+class RecomputeMailboxCountersRequestToTaskTest {
+    @Test
+    void parseOptionsShouldReturnRecheckWhenEmpty() {
+        assertThat(RecomputeMailboxCountersRequestToTask.parseOptions(Optional.empty()))
+            .isEqualTo(Options.recheckMessageDenormalization());
+    }
+
+    @Test
+    void parseOptionsShouldReturnRecheckWhenFalse() {
+        assertThat(RecomputeMailboxCountersRequestToTask.parseOptions(Optional.of("false")))
+            .isEqualTo(Options.recheckMessageDenormalization());
+    }
+
+    @Test
+    void parseOptionsShouldBeCaseIncentive() {
+        assertThat(RecomputeMailboxCountersRequestToTask.parseOptions(Optional.of("False")))
+            .isEqualTo(Options.recheckMessageDenormalization());
+    }
+
+    @Test
+    void parseOptionsShouldReturnTrueWhenTrust() {
+        assertThat(RecomputeMailboxCountersRequestToTask.parseOptions(Optional.of("true")))
+            .isEqualTo(Options.trustMessageDenormalization());
+    }
+
+    @Test
+    void parseOptionsShouldFailWhenEmpty() {
+        assertThatThrownBy(() -> RecomputeMailboxCountersRequestToTask.parseOptions(Optional.of("")))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    void parseOptionsShouldFailWhenNotAValidBoolean() {
+        assertThatThrownBy(() -> RecomputeMailboxCountersRequestToTask.parseOptions(Optional.of("zz")))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+}
\ No newline at end of file
diff --git a/src/site/markdown/server/manage-webadmin.md b/src/site/markdown/server/manage-webadmin.md
index 384d4f6..e3823fa 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -491,6 +491,10 @@ Rerunning the task will *eventually* provide the consistent result. As such we a
 In order to ensure being offline, stop the traffic on SMTP, JMAP and IMAP ports, for example via re-configuration or 
 firewall rules.
 
+`trustMessageDenormalization` query parameter can be set to `true`. This will result in a better performance running the
+task at the cost of safety in the face of message denormalization inconsistencies. Defaults to false, which generates 
+additional checks.
+
 #### Recomputing Global JMAP fast message view projection
 
 This action is only available for backends supporting JMAP protocol.


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