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/07/06 01:37:05 UTC

[james-project] 03/05: JAMES-3095 MailboxValidation refactoring

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 e9a6f8e4d8a90c12eb73f7f5a93568a9918a00ec
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Fri Jul 3 15:53:20 2020 +0700

    JAMES-3095 MailboxValidation refactoring
---
 .../apache/james/jmap/model/MailboxFactory.scala   | 172 +++++++++------------
 .../james/jmap/model/MailboxValidationTest.scala   | 109 +++++--------
 2 files changed, 116 insertions(+), 165 deletions(-)

diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala
index 738b0f9..91e63b9 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala
@@ -22,7 +22,6 @@ package org.apache.james.jmap.model
 import javax.inject.Inject
 import org.apache.james.jmap.mail.MailboxName.MailboxName
 import org.apache.james.jmap.mail._
-import org.apache.james.jmap.model.UnsignedInt.UnsignedInt
 import org.apache.james.jmap.utils.quotas.QuotaLoader
 import org.apache.james.mailbox._
 import org.apache.james.mailbox.model.MailboxACL.EntryKey
@@ -33,17 +32,26 @@ import scala.jdk.CollectionConverters._
 import scala.jdk.OptionConverters._
 
 object MailboxValidation {
-  def validate(mailboxName: Either[IllegalArgumentException, MailboxName],
-               unreadEmails: Either[NumberFormatException, UnsignedInt],
-               unreadThreads: Either[NumberFormatException, UnsignedInt],
-               totalEmails: Either[NumberFormatException, UnsignedInt],
-               totalThreads: Either[NumberFormatException, UnsignedInt]): Either[Exception, MailboxValidation] = {
+  private def retrieveMailboxName(mailboxPath: MailboxPath, pathDelimiter: Char): Either[IllegalArgumentException, MailboxName] =
+    mailboxPath.getName
+      .split(pathDelimiter)
+      .lastOption match {
+        case Some(name) => MailboxName.validate(name)
+        case None => Left(new IllegalArgumentException("No name for the mailbox found"))
+      }
+
+  def validate(mailboxPath: MailboxPath,
+               pathDelimiter: Char,
+               unreadEmails: Long,
+               unreadThreads: Long,
+               totalEmails: Long,
+               totalThreads: Long): Either[Exception, MailboxValidation] = {
     for {
-      validatedName <- mailboxName
-      validatedUnreadEmails <- unreadEmails.map(UnreadEmails)
-      validatedUnreadThreads <- unreadThreads.map(UnreadThreads)
-      validatedTotalEmails <- totalEmails.map(TotalEmails)
-      validatedTotalThreads <- totalThreads.map(TotalThreads)
+      validatedName <- retrieveMailboxName(mailboxPath, pathDelimiter)
+      validatedUnreadEmails <- UnsignedInt.validate(unreadEmails).map(UnreadEmails)
+      validatedUnreadThreads <- UnsignedInt.validate(unreadThreads).map(UnreadThreads)
+      validatedTotalEmails <- UnsignedInt.validate(totalEmails).map(TotalEmails)
+      validatedTotalThreads <- UnsignedInt.validate(totalThreads).map(TotalThreads)
     } yield MailboxValidation(
       mailboxName = validatedName,
       unreadEmails = validatedUnreadEmails,
@@ -61,14 +69,6 @@ case class MailboxValidation(mailboxName: MailboxName,
 
 class MailboxFactory @Inject() (subscriptionManager: SubscriptionManager, mailboxManager: MailboxManager) {
 
-  private def retrieveMailboxName(mailboxPath: MailboxPath, mailboxSession: MailboxSession): Either[IllegalArgumentException, MailboxName] =
-    mailboxPath.getName
-      .split(mailboxSession.getPathDelimiter)
-      .lastOption match {
-        case Some(name) => MailboxName.validate(name)
-        case None => Left(new IllegalArgumentException("No name for the mailbox found"))
-      }
-
   private def getRole(mailboxPath: MailboxPath, mailboxSession: MailboxSession): Option[Role] = Role.from(mailboxPath.getName)
     .filter(_ => mailboxPath.belongsTo(mailboxSession)).toScala
 
@@ -117,88 +117,25 @@ class MailboxFactory @Inject() (subscriptionManager: SubscriptionManager, mailbo
              mailboxSession: MailboxSession,
              allMailboxesMetadata: Seq[MailboxMetaData],
              quotaLoader: QuotaLoader): SMono[Mailbox] = {
-
-    val id: MailboxId = mailboxMetaData.getId
-
-    val name: Either[IllegalArgumentException, MailboxName] = retrieveMailboxName(mailboxMetaData.getPath, mailboxSession)
-
-    val role: Option[Role] = getRole(mailboxMetaData.getPath, mailboxSession)
-    val sortOrder: SortOrder = getSortOrder(role)
-    val quotas: SMono[Quotas] = quotaLoader.getQuotas(mailboxMetaData.getPath)
-    val rights: Rights = getRights(mailboxMetaData.getResolvedAcls)
-
     val sanitizedCounters: MailboxCounters = mailboxMetaData.getCounters.sanitize()
-    val unreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen)
-    val unreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen)
-    val totalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount)
-    val totalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount)
-
-    val namespace: MailboxNamespace = getNamespace(mailboxMetaData.getPath, mailboxSession)
-
-    val parentPath: Option[MailboxPath] = getParentPath(mailboxMetaData.getPath, mailboxSession)
 
-    val parentId: Option[MailboxId] = allMailboxesMetadata.filter(otherMetadata => parentPath.contains(otherMetadata.getPath))
-      .map(_.getId)
-      .headOption
-
-    val myRights: MailboxRights = getMyRights(mailboxMetaData.getPath, mailboxMetaData.getResolvedAcls, mailboxSession)
-
-    val isSubscribed: IsSubscribed = retrieveIsSubscribed(mailboxMetaData.getPath, mailboxSession)
-
-    MailboxValidation.validate(name, unreadEmails, unreadThreads, totalEmails, totalThreads) match {
+    MailboxValidation.validate(mailboxMetaData.getPath, mailboxSession.getPathDelimiter, sanitizedCounters.getUnseen, sanitizedCounters.getUnseen, sanitizedCounters.getCount, sanitizedCounters.getCount) match {
       case Left(error) => SMono.raiseError(error)
-      case scala.Right(mailboxValidation) => SMono.fromPublisher(quotas)
-        .map(quotas =>
-          Mailbox(
-            id = id,
-            name = mailboxValidation.mailboxName,
-            parentId = parentId,
-            role = role,
-            sortOrder = sortOrder,
-            unreadEmails = mailboxValidation.unreadEmails,
-            totalEmails = mailboxValidation.totalEmails,
-            unreadThreads = mailboxValidation.unreadThreads,
-            totalThreads = mailboxValidation.totalThreads,
-            myRights = myRights,
-            namespace = namespace,
-            rights = rights,
-            quotas = quotas,
-            isSubscribed = isSubscribed))
-    }
-  }
+      case scala.Right(mailboxValidation) =>
+        SMono.fromPublisher(quotaLoader.getQuotas(mailboxMetaData.getPath))
+          .map(quotas => {
+            val id: MailboxId = mailboxMetaData.getId
+            val role: Option[Role] = getRole(mailboxMetaData.getPath, mailboxSession)
+            val sortOrder: SortOrder = getSortOrder(role)
+            val rights: Rights = getRights(mailboxMetaData.getResolvedAcls)
+            val namespace: MailboxNamespace = getNamespace(mailboxMetaData.getPath, mailboxSession)
+            val parentPath: Option[MailboxPath] = getParentPath(mailboxMetaData.getPath, mailboxSession)
+            val parentId: Option[MailboxId] = allMailboxesMetadata.filter(otherMetadata => parentPath.contains(otherMetadata.getPath))
+              .map(_.getId)
+              .headOption
+            val myRights: MailboxRights = getMyRights(mailboxMetaData.getPath, mailboxMetaData.getResolvedAcls, mailboxSession)
+            val isSubscribed: IsSubscribed = retrieveIsSubscribed(mailboxMetaData.getPath, mailboxSession)
 
-  def create(id: MailboxId, mailboxSession: MailboxSession, quotaLoader: QuotaLoader): SMono[Mailbox] = {
-    try {
-      val messageManager: MessageManager = mailboxManager.getMailbox(id, mailboxSession)
-      val resolvedACL = messageManager.getResolvedAcl(mailboxSession)
-
-      val name: Either[IllegalArgumentException, MailboxName] = retrieveMailboxName(messageManager.getMailboxPath, mailboxSession)
-
-      val role: Option[Role] = getRole(messageManager.getMailboxPath, mailboxSession)
-      val sortOrder: SortOrder = getSortOrder(role)
-      val quotas: SMono[Quotas] = quotaLoader.getQuotas(messageManager.getMailboxPath)
-      val rights: Rights = getRights(resolvedACL)
-
-      val sanitizedCounters: MailboxCounters = messageManager.getMailboxCounters(mailboxSession).sanitize()
-      val unreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen)
-      val unreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen)
-      val totalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount)
-      val totalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount)
-
-      val namespace: MailboxNamespace = getNamespace(messageManager.getMailboxPath, mailboxSession)
-
-      val parentId: Option[MailboxId] = getParentPath(messageManager.getMailboxPath, mailboxSession)
-        .map(parentPath => mailboxManager.getMailbox(parentPath, mailboxSession))
-        .map(_.getId)
-
-      val myRights: MailboxRights = getMyRights(messageManager.getMailboxPath, resolvedACL, mailboxSession)
-
-      val isSubscribed: IsSubscribed = retrieveIsSubscribed(messageManager.getMailboxPath, mailboxSession)
-
-      MailboxValidation.validate(name, unreadEmails, unreadThreads, totalEmails, totalThreads) match {
-        case Left(error) => SMono.raiseError(error)
-        case scala.Right(mailboxValidation) => SMono.fromPublisher(quotas)
-          .map(quotas =>
             Mailbox(
               id = id,
               name = mailboxValidation.mailboxName,
@@ -213,7 +150,46 @@ class MailboxFactory @Inject() (subscriptionManager: SubscriptionManager, mailbo
               namespace = namespace,
               rights = rights,
               quotas = quotas,
-              isSubscribed = isSubscribed))
+              isSubscribed = isSubscribed)})
+    }
+  }
+
+  def create(id: MailboxId, mailboxSession: MailboxSession, quotaLoader: QuotaLoader): SMono[Mailbox] = {
+    try {
+      val messageManager: MessageManager = mailboxManager.getMailbox(id, mailboxSession)
+      val sanitizedCounters: MailboxCounters = messageManager.getMailboxCounters(mailboxSession).sanitize()
+
+      MailboxValidation.validate(messageManager.getMailboxPath, mailboxSession.getPathDelimiter, sanitizedCounters.getUnseen, sanitizedCounters.getUnseen, sanitizedCounters.getCount, sanitizedCounters.getCount) match {
+        case Left(error) => SMono.raiseError(error)
+        case scala.Right(mailboxValidation) =>
+          SMono.fromPublisher(quotaLoader.getQuotas(messageManager.getMailboxPath))
+            .map(quotas => {
+              val resolvedACL = messageManager.getResolvedAcl(mailboxSession)
+              val role: Option[Role] = getRole(messageManager.getMailboxPath, mailboxSession)
+              val sortOrder: SortOrder = getSortOrder(role)
+              val rights: Rights = getRights(resolvedACL)
+              val namespace: MailboxNamespace = getNamespace(messageManager.getMailboxPath, mailboxSession)
+              val parentId: Option[MailboxId] = getParentPath(messageManager.getMailboxPath, mailboxSession)
+                .map(parentPath => mailboxManager.getMailbox(parentPath, mailboxSession))
+                .map(_.getId)
+              val myRights: MailboxRights = getMyRights(messageManager.getMailboxPath, resolvedACL, mailboxSession)
+              val isSubscribed: IsSubscribed = retrieveIsSubscribed(messageManager.getMailboxPath, mailboxSession)
+
+              Mailbox(
+                id = id,
+                name = mailboxValidation.mailboxName,
+                parentId = parentId,
+                role = role,
+                sortOrder = sortOrder,
+                unreadEmails = mailboxValidation.unreadEmails,
+                totalEmails = mailboxValidation.totalEmails,
+                unreadThreads = mailboxValidation.unreadThreads,
+                totalThreads = mailboxValidation.totalThreads,
+                myRights = myRights,
+                namespace = namespace,
+                rights = rights,
+                quotas = quotas,
+                isSubscribed = isSubscribed)})
       }
     } catch {
       case error: Exception => SMono.raiseError(error)
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala
index bbc5e06..dc54d01 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala
@@ -20,14 +20,19 @@
 package org.apache.james.jmap.model
 
 import eu.timepit.refined.auto._
+import org.apache.james.core.Username
 import org.apache.james.jmap.mail.MailboxName.MailboxName
 import org.apache.james.jmap.mail._
 import org.apache.james.jmap.model.UnsignedInt.UnsignedInt
+import org.apache.james.mailbox.model.MailboxPath
 import org.scalatest.matchers.must.Matchers
 import org.scalatest.wordspec.AnyWordSpec
 
 object MailboxValidationTest {
   private val mailboxName: MailboxName = "name"
+  private val user: Username = Username.of("user")
+  private val mailboxPath: MailboxPath = MailboxPath.forUser(user, mailboxName)
+  private val pathDelimiter: Char = '.'
   private val unreadEmails: UnsignedInt = 1L
   private val unreadThreads: UnsignedInt = 2L
   private val totalEmails: UnsignedInt = 3L
@@ -39,12 +44,6 @@ class MailboxValidationTest extends AnyWordSpec with Matchers {
 
   "MailboxValidation" should {
     "succeed" in {
-      val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName)
-      val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails)
-      val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads)
-      val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails)
-      val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads)
-
       val expectedResult: Either[Exception, MailboxValidation] = scala.Right(MailboxValidation(
         mailboxName = mailboxName,
         unreadEmails = UnreadEmails(unreadEmails),
@@ -53,86 +52,62 @@ class MailboxValidationTest extends AnyWordSpec with Matchers {
         totalThreads = TotalThreads(totalThreads)))
 
       MailboxValidation.validate(
-        validMailboxname,
-        validUnreadEmails,
-        validUnreadThreads,
-        validTotalEmails,
-        validTotalThreads) must be(expectedResult)
+        mailboxPath,
+        pathDelimiter,
+        unreadEmails.value,
+        unreadThreads.value,
+        totalEmails.value,
+        totalThreads.value) must be(expectedResult)
     }
 
-    "fail when mailboxName is invalid" in {
-      val invalidMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate("")
-      val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails)
-      val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads)
-      val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails)
-      val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads)
-
+    "fail when mailboxPath is invalid" in {
       MailboxValidation.validate(
-        invalidMailboxname,
-        validUnreadEmails,
-        validUnreadThreads,
-        validTotalEmails,
-        validTotalThreads) mustBe a[Left[_, _]]
+        MailboxPath.forUser(user, ""),
+        pathDelimiter,
+        unreadEmails.value,
+        unreadThreads.value,
+        totalEmails.value,
+        totalThreads.value) mustBe a[Left[_, _]]
     }
 
     "fail when unreadEmails is invalid" in {
-      val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName)
-      val invalidUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L)
-      val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads)
-      val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails)
-      val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads)
-
       MailboxValidation.validate(
-        validMailboxname,
-        invalidUnreadEmails,
-        validUnreadThreads,
-        validTotalEmails,
-        validTotalThreads) mustBe a[Left[_, _]]
+        mailboxPath,
+        pathDelimiter,
+        -1L,
+        unreadThreads.value,
+        totalEmails.value,
+        totalThreads.value) mustBe a[Left[_, _]]
     }
 
     "fail when unreadThreads is invalid" in {
-      val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName)
-      val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails)
-      val invalidUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L)
-      val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails)
-      val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads)
-
       MailboxValidation.validate(
-        validMailboxname,
-        validUnreadEmails,
-        invalidUnreadThreads,
-        validTotalEmails,
-        validTotalThreads) mustBe a[Left[_, _]]
+        mailboxPath,
+        pathDelimiter,
+        unreadEmails.value,
+        -1L,
+        totalEmails.value,
+        totalThreads.value) mustBe a[Left[_, _]]
     }
 
     "fail when totalEmails is invalid" in {
-      val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName)
-      val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails)
-      val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads)
-      val invalidTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L)
-      val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads)
-
       MailboxValidation.validate(
-        validMailboxname,
-        validUnreadEmails,
-        validUnreadThreads,
-        invalidTotalEmails,
-        validTotalThreads) mustBe a[Left[_, _]]
+        mailboxPath,
+        pathDelimiter,
+        unreadEmails.value,
+        unreadThreads.value,
+        -1L,
+        totalThreads.value) mustBe a[Left[_, _]]
     }
 
     "fail when totalThreads is invalid" in {
-      val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName)
-      val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails)
-      val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads)
-      val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails)
-      val invalidTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L)
-
       MailboxValidation.validate(
-        validMailboxname,
-        validUnreadEmails,
-        validUnreadThreads,
-        validTotalEmails,
-        invalidTotalThreads) mustBe a[Left[_, _]]
+        mailboxPath,
+        pathDelimiter,
+        unreadEmails.value,
+        unreadThreads.value,
+        totalEmails.value,
+        -1L) mustBe a[Left[_, _]]
     }
   }
 }


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