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 rc...@apache.org on 2020/06/08 03:12:30 UTC

[james-project] 09/16: JAMES-3171 Port QuotaLoader to jmap-rfc8621

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

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

commit 8ba14ba0184a7b8b9a716e0ffcd241894b68c8e2
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Wed May 20 11:06:27 2020 +0700

    JAMES-3171 Port QuotaLoader to jmap-rfc8621
---
 .../scala/org/apache/james/jmap/mail/Quotas.scala  | 10 ++--
 .../org/apache/james/jmap/model/UnsignedInt.scala  | 12 ++++-
 .../quotas/QuotaLoader.scala}                      | 25 ++++-----
 .../quotas/QuotaLoaderWithPreloadedDefault.scala   | 60 ++++++++++++++++++++++
 .../james/jmap/utils/quotas/QuotaReader.scala      | 52 +++++++++++++++++++
 5 files changed, 142 insertions(+), 17 deletions(-)

diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Quotas.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Quotas.scala
index c9d4212..e107efe 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Quotas.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Quotas.scala
@@ -21,16 +21,16 @@ package org.apache.james.jmap.mail
 
 import org.apache.james.core.Domain
 import org.apache.james.jmap.model.UnsignedInt.UnsignedInt
-import org.apache.james.mailbox.model.{QuotaRoot => JavaQuotaRoot}
+import org.apache.james.mailbox.model.{QuotaRoot => ModelQuotaRoot}
 
 import scala.compat.java8.OptionConverters._
 
 object QuotaRoot{
-  def fromJava(quotaRoot: JavaQuotaRoot) = QuotaRoot(quotaRoot.getValue, quotaRoot.getDomain.asScala)
+  def toJmap(quotaRoot: ModelQuotaRoot) = QuotaRoot(quotaRoot.getValue, quotaRoot.getDomain.asScala)
 }
 
 case class QuotaRoot(value: String, domain: Option[Domain]) {
-  def asJava: JavaQuotaRoot = JavaQuotaRoot.quotaRoot(value, domain.asJava)
+  def toModel: ModelQuotaRoot = ModelQuotaRoot.quotaRoot(value, domain.asJava)
 }
 
 object Quotas {
@@ -51,6 +51,10 @@ case class QuotaId(quotaRoot: QuotaRoot) extends AnyVal {
   def getName: String = quotaRoot.value
 }
 
+object Quota {
+  def from(quota: Map[Quotas.Type, Value]) = new Quota(quota)
+}
+
 case class Quota(quota: Map[Quotas.Type, Value]) extends AnyVal
 
 case class Value(used: UnsignedInt, max: Option[UnsignedInt])
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/UnsignedInt.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/UnsignedInt.scala
index 3b51240..2fae439 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/UnsignedInt.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/UnsignedInt.scala
@@ -19,11 +19,19 @@
 
 package org.apache.james.jmap.model
 
+import eu.timepit.refined
 import eu.timepit.refined.api.Refined
 import eu.timepit.refined.numeric.Interval.Closed
 
 object UnsignedInt {
-//Unsigned int between [0, 2^53]
-type UnsignedInt = Long Refined Closed[0L, 9007199254740992L]
+  //Unsigned int between [0, 2^53]
+  type UnsignedIntConstraint = Closed[0L, 9007199254740992L]
+  type UnsignedInt = Long Refined UnsignedIntConstraint
+
+  def liftOrThrow(value: Long): UnsignedInt =
+    refined.refineV[UnsignedIntConstraint](value) match {
+      case Right(value) => value
+      case Left(error) => throw new IllegalArgumentException(error)
+    }
 
 }
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/UnsignedInt.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoader.scala
similarity index 56%
copy from server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/UnsignedInt.scala
copy to server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoader.scala
index 3b51240..0c770c7 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/UnsignedInt.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoader.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        *
@@ -6,24 +6,25 @@
  * 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                 *
- * *
+ *                                                              *
+ *   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.jmap.model
+package org.apache.james.jmap.utils.quotas
 
-import eu.timepit.refined.api.Refined
-import eu.timepit.refined.numeric.Interval.Closed
-
-object UnsignedInt {
-//Unsigned int between [0, 2^53]
-type UnsignedInt = Long Refined Closed[0L, 9007199254740992L]
+import org.apache.james.jmap.mail.Quotas
+import org.apache.james.mailbox.exception.MailboxException
+import org.apache.james.mailbox.model.MailboxPath
+import reactor.core.scala.publisher.SMono
 
+trait QuotaLoader {
+  @throws[MailboxException]
+  def getQuotas(mailboxPath: MailboxPath): SMono[Quotas]
 }
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoaderWithPreloadedDefault.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoaderWithPreloadedDefault.scala
new file mode 100644
index 0000000..8a4c458
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoaderWithPreloadedDefault.scala
@@ -0,0 +1,60 @@
+/****************************************************************
+ * 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.jmap.utils.quotas
+
+import javax.inject.Inject
+import org.apache.james.jmap.mail.{QuotaRoot, Quotas}
+import org.apache.james.mailbox.MailboxSession
+import org.apache.james.mailbox.exception.MailboxException
+import org.apache.james.mailbox.model.{MailboxPath, QuotaRoot => ModelQuotaRoot}
+import org.apache.james.mailbox.quota.UserQuotaRootResolver
+import reactor.core.scala.publisher.SMono
+
+
+class QuotaLoaderWithPreloadedDefaultFactory @Inject()(quotaRootResolver: UserQuotaRootResolver, quotaReader: QuotaReader) {
+
+  def loadFor(session: MailboxSession): SMono[QuotaLoaderWithPreloadedDefault] =
+    SMono.fromCallable(() => new QuotaLoaderWithPreloadedDefault(
+        quotaRootResolver,
+        quotaReader,
+        session,
+        getUserDefaultQuotas(session)))
+
+
+  @throws[MailboxException]
+  private def getUserDefaultQuotas(session:MailboxSession): SMono[Quotas] = {
+    val quotaRoot: ModelQuotaRoot = quotaRootResolver.forUser(session.getUser)
+    quotaReader.retrieveQuotas(QuotaRoot.toJmap(quotaRoot))
+  }
+}
+
+class QuotaLoaderWithPreloadedDefault(quotaRootResolver: UserQuotaRootResolver,
+                                      quotaReader: QuotaReader,
+                                      session: MailboxSession,
+                                      preloadedUserDefaultQuotas: SMono[Quotas]) extends QuotaLoader {
+  @throws[MailboxException]
+  override def getQuotas(mailboxPath: MailboxPath): SMono[Quotas] =
+    if (mailboxPath.belongsTo(session)) {
+      preloadedUserDefaultQuotas
+    } else {
+      val quotaRoot: ModelQuotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath)
+      quotaReader.retrieveQuotas(QuotaRoot.toJmap(quotaRoot))
+    }
+}
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaReader.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaReader.scala
new file mode 100644
index 0000000..2545c83
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaReader.scala
@@ -0,0 +1,52 @@
+/****************************************************************
+ * 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.jmap.utils.quotas
+
+import javax.inject.Inject
+import org.apache.james.core.quota.{QuotaLimitValue, QuotaUsageValue}
+import org.apache.james.jmap.mail._
+import org.apache.james.jmap.model.UnsignedInt
+import org.apache.james.jmap.model.UnsignedInt.UnsignedInt
+import org.apache.james.mailbox.exception.MailboxException
+import org.apache.james.mailbox.model.{Quota => ModelQuota}
+import org.apache.james.mailbox.quota.QuotaManager
+import reactor.core.scala.publisher.SMono
+
+class QuotaReader @Inject() (quotaManager: QuotaManager) {
+  @throws[MailboxException]
+  def retrieveQuotas(quotaRoot: QuotaRoot): SMono[Quotas] =
+    SMono.just(Quotas.from(
+      QuotaId.fromQuotaRoot(quotaRoot),
+      Quota.from(Map(
+        Quotas.Storage -> quotaToValue(quotaManager.getStorageQuota(quotaRoot.toModel)),
+        Quotas.Message -> quotaToValue(quotaManager.getMessageQuota(quotaRoot.toModel))))))
+
+  private def quotaToValue[T <: QuotaLimitValue[T], U <: QuotaUsageValue[U, T]](quota: ModelQuota[T, U]): Value =
+    Value(
+      UnsignedInt.liftOrThrow(quota.getUsed.asLong),
+      asNumber(quota.getLimit))
+
+  private def asNumber(value: QuotaLimitValue[_]): Option[UnsignedInt] =
+    if (value.isUnlimited) {
+      None
+    } else {
+      Some(UnsignedInt.liftOrThrow(value.asLong))
+    }
+}


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