You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/04/26 06:13:00 UTC

[james-project] branch master updated (fa8fefd263 -> 76b0050f2c)

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

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


    from fa8fefd263 [DOCUMENTATION] Recommend the use of PROXY protocol
     new f120b369ce Use extension method pattern to replace utility methods
     new 9ba4f24b98 Simplify PerRecipientRateLimit init
     new 76e41ed234 Make EntityType more idiomatic
     new 31f3000db4 Switch from OOP style to FP style
     new f51addb539 Avoid some repetition
     new 2ab7257ed2 GlobalRateLimiter can't be a case class as it contains a class
     new a784fa5c0d When we don't get any limiter, don't build a global rate limiter
     new 923fab4f35 Throwing methods are uncommon in scala, let's throw at scala/java boundary
     new 76b0050f2c Rename RecipientType to Recipient

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../james/rate/limiter/api/RateLimiter.scala       |  24 +----
 .../james/transport/mailets/EntityType.scala       | 114 ++++++++++-----------
 .../james/transport/mailets/GlobalRateLimit.scala  |  53 ++++++----
 .../transport/mailets/PerRecipientRateLimit.scala  |  24 ++---
 .../transport/mailets/PerSenderRateLimit.scala     |  19 ++--
 5 files changed, 113 insertions(+), 121 deletions(-)


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


[james-project] 06/09: GlobalRateLimiter can't be a case class as it contains a class

Posted by bt...@apache.org.
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 2ab7257ed2d0adf1b5794a6c78b30e14cade655d
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Fri Feb 10 09:04:56 2023 +0100

    GlobalRateLimiter can't be a case class as it contains a class
---
 .../scala/org/apache/james/transport/mailets/GlobalRateLimit.scala    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
index 4ea602fa6d..c446f48875 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
@@ -37,7 +37,7 @@ case class GlobalKey(keyPrefix: Option[KeyPrefix], entityType: EntityType) exten
   }
 }
 
-case class GlobalRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Option[KeyPrefix], entityType: EntityType) {
+class GlobalRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Option[KeyPrefix], entityType: EntityType) {
   def rateLimit(mail: Mail): Publisher[RateLimitingResult] = {
     val rateLimitingKey = GlobalKey(keyPrefix, entityType)
 
@@ -143,7 +143,7 @@ class GlobalRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) extends
 
   private def createRateLimiter(rateLimiterFactory: RateLimiterFactory, entityType: EntityType, keyPrefix: Option[KeyPrefix],
                                 duration: Duration, precision: Option[Duration]): GlobalRateLimiter =
-    GlobalRateLimiter(rateLimiter = EntityType.extractRules(entityType, duration, getMailetConfig)
+    new GlobalRateLimiter(rateLimiter = EntityType.extractRules(entityType, duration, getMailetConfig)
       .map(rateLimiterFactory.withSpecification(_, precision)),
       keyPrefix = keyPrefix,
       entityType = entityType)


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


[james-project] 01/09: Use extension method pattern to replace utility methods

Posted by bt...@apache.org.
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 f120b369cefdefe5695387661fd234dca90dffac
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Thu Feb 9 21:29:22 2023 +0100

    Use extension method pattern to replace utility methods
---
 .../org/apache/james/transport/mailets/EntityType.scala    | 14 ++++++--------
 .../apache/james/transport/mailets/GlobalRateLimit.scala   | 13 +++++++------
 .../james/transport/mailets/PerRecipientRateLimit.scala    |  9 +++++----
 .../james/transport/mailets/PerSenderRateLimit.scala       |  9 +++++----
 4 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
index ca65489936..4fbbebd009 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
@@ -32,17 +32,15 @@ import scala.util.Try
 
 case class KeyPrefix(value: String)
 
-object DurationParsingUtil {
-  def parseDuration(mailetConfig: MailetConfig): Duration = Option(mailetConfig.getInitParameter("duration"))
-    .map(string => DurationParser.parse(string, ChronoUnit.SECONDS))
-    .getOrElse(throw new IllegalArgumentException("'duration' is compulsory"))
-}
+object ConfigurationOps {
+  implicit class DurationOps(mailetConfig: MailetConfig) {
+    def getDuration(key: String): Option[Duration] = Option(mailetConfig.getInitParameter(key))
+      .map(string => DurationParser.parse(string, ChronoUnit.SECONDS))
+  }
 
-object PrecisionParsingUtil {
-  def parsePrecision(mailetConfig: MailetConfig): Option[Duration] = Option(mailetConfig.getInitParameter("precision"))
-    .map(string => DurationParser.parse(string, ChronoUnit.SECONDS))
 }
 
+
 sealed trait EntityType {
   def asString(): String
 
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
index a0f119111e..0e1b3ecf7c 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
@@ -21,8 +21,8 @@ package org.apache.james.transport.mailets
 
 import java.time.Duration
 import java.util
-
 import com.google.common.collect.ImmutableList
+
 import javax.inject.Inject
 import org.apache.james.rate.limiter.api.{AcceptableRate, RateExceeded, RateLimiter, RateLimiterFactory, RateLimitingKey, RateLimitingResult}
 import org.apache.mailet.base.GenericMailet
@@ -108,8 +108,12 @@ class GlobalRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) extends
   private var keyPrefix: Option[KeyPrefix] = _
 
   override def init(): Unit = {
-    val duration: Duration = parseDuration()
-    val precision: Option[Duration] = parsePrecision()
+    import org.apache.james.transport.mailets.ConfigurationOps.DurationOps
+
+    val duration: Duration = getMailetConfig.getDuration("duration")
+      .getOrElse(throw new IllegalArgumentException("'duration' is compulsory"))
+
+    val precision: Option[Duration] = getMailetConfig.getDuration("precision")
 
     keyPrefix = Option(getInitParameter("keyPrefix")).map(KeyPrefix)
     exceededProcessor = getInitParameter("exceededProcessor", Mail.ERROR)
@@ -122,9 +126,6 @@ class GlobalRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) extends
     totalSizeRateLimiter = globalRateLimiter(TotalSize)
   }
 
-  def parseDuration(): Duration = DurationParsingUtil.parseDuration(getMailetConfig)
-  def parsePrecision(): Option[Duration] = PrecisionParsingUtil.parsePrecision(getMailetConfig)
-
   override def service(mail: Mail): Unit = {
     val pivot: RateLimitingResult = AcceptableRate
     val result = SFlux.merge(Seq(
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
index dd65a01138..0e0a4b16a9 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
@@ -21,13 +21,14 @@ package org.apache.james.transport.mailets
 
 import java.time.Duration
 import java.util
-
 import com.google.common.annotations.VisibleForTesting
 import com.google.common.collect.ImmutableList
+
 import javax.inject.Inject
 import org.apache.james.core.MailAddress
 import org.apache.james.lifecycle.api.LifecycleUtil
 import org.apache.james.rate.limiter.api.{AcceptableRate, RateExceeded, RateLimiter, RateLimiterFactory, RateLimitingKey, RateLimitingResult}
+import org.apache.james.transport.mailets.ConfigurationOps.DurationOps
 import org.apache.james.util.ReactorUtils.DEFAULT_CONCURRENCY
 import org.apache.mailet.base.GenericMailet
 import org.apache.mailet.{Mail, ProcessingState}
@@ -98,7 +99,7 @@ class PerRecipientRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) ex
 
   override def init(): Unit = {
     val duration: Duration = parseDuration()
-    val precision: Option[Duration] = parsePrecision()
+    val precision: Option[Duration] = getMailetConfig.getDuration("precision")
     val keyPrefix: Option[KeyPrefix] = Option(getInitParameter("keyPrefix")).map(KeyPrefix)
     exceededProcessor = getInitParameter("exceededProcessor", Mail.ERROR)
 
@@ -132,8 +133,8 @@ class PerRecipientRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) ex
   }
 
   @VisibleForTesting
-  def parseDuration(): Duration = DurationParsingUtil.parseDuration(getMailetConfig)
-  def parsePrecision(): Option[Duration] = PrecisionParsingUtil.parsePrecision(getMailetConfig)
+  def parseDuration(): Duration = getMailetConfig.getDuration("duration")
+    .getOrElse(throw new IllegalArgumentException("'duration' is compulsory"))
 
   private def createRateLimiter(entityType: EntityType, duration: Duration, precision: Option[Duration],
                                 rateLimiterFactory: RateLimiterFactory, keyPrefix: Option[KeyPrefix]): Option[PerRecipientRateLimiter] =
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
index 956d063f90..c48831d9a9 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
@@ -21,12 +21,13 @@ package org.apache.james.transport.mailets
 
 import java.time.Duration
 import java.util
-
 import com.google.common.annotations.VisibleForTesting
 import com.google.common.collect.ImmutableList
+
 import javax.inject.Inject
 import org.apache.james.core.MailAddress
 import org.apache.james.rate.limiter.api.{AcceptableRate, RateExceeded, RateLimiter, RateLimiterFactory, RateLimitingKey, RateLimitingResult}
+import org.apache.james.transport.mailets.ConfigurationOps.DurationOps
 import org.apache.mailet.base.GenericMailet
 import org.apache.mailet.{Mail, ProcessingState}
 import org.reactivestreams.Publisher
@@ -109,7 +110,7 @@ class PerSenderRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) exten
 
   override def init(): Unit = {
     val duration: Duration = parseDuration()
-    val precision: Option[Duration] = parsePrecision()
+    val precision: Option[Duration] = getMailetConfig.getDuration("precision")
 
     keyPrefix = Option(getInitParameter("keyPrefix")).map(KeyPrefix)
     exceededProcessor = getInitParameter("exceededProcessor", Mail.ERROR)
@@ -123,8 +124,8 @@ class PerSenderRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) exten
   }
 
   @VisibleForTesting
-  def parseDuration(): Duration = DurationParsingUtil.parseDuration(getMailetConfig)
-  def parsePrecision(): Option[Duration] = PrecisionParsingUtil.parsePrecision(getMailetConfig)
+  def parseDuration(): Duration = getMailetConfig.getDuration("duration")
+    .getOrElse(throw new IllegalArgumentException("'duration' is compulsory"))
 
   override def service(mail: Mail): Unit = mail.getMaybeSender
       .asOptional()


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


[james-project] 08/09: Throwing methods are uncommon in scala, let's throw at scala/java boundary

Posted by bt...@apache.org.
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 923fab4f35cecdf5a89c51e8b72bdbfc66144b78
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Wed Feb 22 20:53:55 2023 +0100

    Throwing methods are uncommon in scala, let's throw at scala/java boundary
---
 .../james/rate/limiter/api/RateLimiter.scala       | 24 ++++------------------
 .../james/transport/mailets/EntityType.scala       | 19 +++++++++++++----
 2 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/rate/limiter/api/RateLimiter.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/rate/limiter/api/RateLimiter.scala
index c02c1aa9f0..9eda3cc7b7 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/rate/limiter/api/RateLimiter.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/rate/limiter/api/RateLimiter.scala
@@ -37,16 +37,8 @@ object AllowedQuantity {
   type AllowedQuantity = Long Refined PositiveLongConstraint
 
   def validate(value: Long): Either[NumberFormatException, AllowedQuantity] =
-    refined.refineV[PositiveLongConstraint](value) match {
-      case Right(value) => Right(value)
-      case Left(error) => Left(new NumberFormatException(error))
-    }
-
-  def liftOrThrow(value: Long): AllowedQuantity =
-    validate(value) match {
-      case Right(value) => value
-      case Left(error) => throw error
-    }
+    refined.refineV[PositiveLongConstraint](value)
+      .left.map(error => new NumberFormatException(error))
 }
 
 object Increment {
@@ -54,16 +46,8 @@ object Increment {
   type Increment = Int Refined PositiveLongConstraint
 
   def validate(value: Int): Either[NumberFormatException, Increment] =
-    refined.refineV[PositiveLongConstraint](value) match {
-      case Right(value) => Right(value)
-      case Left(error) => Left(new NumberFormatException(error))
-    }
-
-  def liftOrThrow(value: Int): Increment =
-    validate(value) match {
-      case Right(value) => value
-      case Left(error) => throw error
-    }
+    refined.refineV[PositiveLongConstraint](value)
+      .left.map(error => new NumberFormatException(error))
 }
 
 case class Rule(quantity: AllowedQuantity, duration: Duration)
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
index ead8e82b97..a93bfb53cc 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
@@ -56,21 +56,32 @@ object ConfigurationOps {
 }
 
 object EntityType {
+
+  implicit class EitherOps[E <: Throwable, A](either: Either[E, A]) {
+    def orThrow(message: String): A = either.left.map(cause => new IllegalArgumentException(message, cause)).toTry.get
+  }
+
   def extractRules(entityType: EntityType, duration: Duration, mailetConfig: MailetConfig): Option[Rules] = (entityType match {
     case Count          => mailetConfig.getOptionalLong("count")
     case RecipientsType => mailetConfig.getOptionalLong("recipients")
     case Size           => mailetConfig.getOptionalSize("size").map(_.asBytes())
     case TotalSize      => mailetConfig.getOptionalSize("totalSize").map(_.asBytes())
-  }).map(AllowedQuantity.liftOrThrow)
+  }).map(AllowedQuantity.validate(_).orThrow(s"invalid quantity for ${entityType.asString}"))
     .map(quantity => Rules(Seq(Rule(quantity, duration))))
 
   def extractQuantity(entityType: EntityType, mail: Mail): Option[Increment] = entityType match {
     case Count          => Some(1)
-    case RecipientsType => Some(Increment.liftOrThrow(mail.getRecipients.size()))
-    case Size           => Some(Increment.liftOrThrow(mail.getMessageSize.toInt))
+    case RecipientsType =>
+      Some(Increment
+        .validate(mail.getRecipients.size())
+        .orThrow(s"invalid quantity for ${entityType.asString}"))
+    case Size           =>
+      Some(Increment
+        .validate(mail.getMessageSize.toInt)
+        .orThrow(s"invalid quantity for ${entityType.asString}"))
     case TotalSize      =>
       Try(Math.multiplyExact(mail.getMessageSize.toInt, mail.getRecipients.size()))
-        .map(Increment.liftOrThrow)
+        .map(Increment.validate(_).orThrow(s"invalid quantity for ${entityType.asString}"))
         .toOption
   }
 }


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


[james-project] 05/09: Avoid some repetition

Posted by bt...@apache.org.
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 f51addb539d755569135c03eb14d0bc0bb678482
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Fri Feb 10 09:03:14 2023 +0100

    Avoid some repetition
---
 .../org/apache/james/transport/mailets/GlobalRateLimit.scala      | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
index cf19976483..4ea602fa6d 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
@@ -31,10 +31,10 @@ import org.reactivestreams.Publisher
 import reactor.core.scala.publisher.{SFlux, SMono}
 
 case class GlobalKey(keyPrefix: Option[KeyPrefix], entityType: EntityType) extends RateLimitingKey {
-  val globalPrefix: String = "global"
-
-  override def asString(): String = keyPrefix.map(prefix => s"${prefix.value}_${entityType.asString}_$globalPrefix}")
-    .getOrElse(s"${entityType.asString}_$globalPrefix")
+  override val asString: String = {
+    val key = s"${entityType.asString}_global}"
+    keyPrefix.map(prefix => s"${prefix.value}_$key").getOrElse(key)
+  }
 }
 
 case class GlobalRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Option[KeyPrefix], entityType: EntityType) {


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


[james-project] 03/09: Make EntityType more idiomatic

Posted by bt...@apache.org.
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 76e41ed2340c03138d5053ff82beccc614860747
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Thu Feb 9 21:53:35 2023 +0100

    Make EntityType more idiomatic
---
 .../james/transport/mailets/EntityType.scala       | 32 ++++++++++------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
index cf9d87b979..0751bb6a35 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
@@ -21,10 +21,10 @@ package org.apache.james.transport.mailets
 
 import java.time.Duration
 import java.time.temporal.ChronoUnit
-
 import eu.timepit.refined.auto._
 import org.apache.james.rate.limiter.api.Increment.Increment
 import org.apache.james.rate.limiter.api.{AllowedQuantity, Increment, Rule, Rules}
+import org.apache.james.transport.mailets.ConfigurationOps.{OptionOps, SizeOps}
 import org.apache.james.util.DurationParser
 import org.apache.mailet.{Mail, MailetConfig}
 
@@ -36,12 +36,22 @@ object ConfigurationOps {
 
   implicit class OptionOps(mailetConfig: MailetConfig) {
     def getOptionalString(key: String): Option[String] = Option(mailetConfig.getInitParameter(key))
+    def getOptionalLong(key: String): Option[Long] = Option(mailetConfig.getInitParameter(key)).map(_.toLong)
   }
 
   implicit class DurationOps(mailetConfig: MailetConfig) {
     def getDuration(key: String): Option[Duration] = mailetConfig.getOptionalString(key)
       .map(string => DurationParser.parse(string, ChronoUnit.SECONDS))
   }
+
+  implicit class SizeOps(mailetConfig: MailetConfig) {
+    def getOptionalSize(key: String): Option[org.apache.james.util.Size] = mailetConfig.getOptionalString(key)
+      .map {
+        case "" => throw new IllegalArgumentException(s"'$key' field cannot be empty if specified")
+        case s => s
+      }
+      .map(org.apache.james.util.Size.parse)
+  }
 }
 
 
@@ -58,8 +68,7 @@ case object Count extends EntityType {
 
   override def extractQuantity(mail: Mail): Option[Increment] = Some(1)
 
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = Option(mailetConfig.getInitParameter("count"))
-    .map(_.toLong)
+  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalLong("count")
     .map(AllowedQuantity.liftOrThrow)
     .map(quantity => Rules(Seq(Rule(quantity, duration))))
 }
@@ -69,8 +78,7 @@ case object RecipientsType extends EntityType {
 
   override def extractQuantity(mail: Mail): Option[Increment] = Some(Increment.liftOrThrow(mail.getRecipients.size()))
 
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = Option(mailetConfig.getInitParameter("recipients"))
-    .map(_.toLong)
+  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalLong("recipients")
     .map(AllowedQuantity.liftOrThrow)
     .map(quantity => Rules(Seq(Rule(quantity, duration))))
 }
@@ -80,12 +88,7 @@ case object Size extends EntityType {
 
   override def extractQuantity(mail: Mail): Option[Increment] = Some(Increment.liftOrThrow(mail.getMessageSize.toInt))
 
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = Option(mailetConfig.getInitParameter("size"))
-    .map {
-      case "" => throw new IllegalArgumentException("'size' field cannot be empty if specified")
-      case s => s
-    }
-    .map(org.apache.james.util.Size.parse)
+  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalSize("size")
     .map(_.asBytes())
     .map(AllowedQuantity.liftOrThrow)
     .map(quantity => Rules(Seq(Rule(quantity, duration))))
@@ -99,12 +102,7 @@ case object TotalSize extends EntityType {
       .map(Increment.liftOrThrow)
       .toOption
 
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = Option(mailetConfig.getInitParameter("totalSize"))
-    .map {
-      case "" => throw new IllegalArgumentException("'totalSize' field cannot be empty if specified")
-      case s => s
-    }
-    .map(org.apache.james.util.Size.parse)
+  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalSize("totalSize")
     .map(_.asBytes())
     .map(AllowedQuantity.liftOrThrow)
     .map(quantity => Rules(Seq(Rule(quantity, duration))))


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


[james-project] 04/09: Switch from OOP style to FP style

Posted by bt...@apache.org.
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 31f3000db4395415c3c2b4477811601a310e6a5c
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Fri Feb 10 08:55:44 2023 +0100

    Switch from OOP style to FP style
---
 .../james/transport/mailets/EntityType.scala       | 69 +++++++++-------------
 .../james/transport/mailets/GlobalRateLimit.scala  |  8 +--
 .../transport/mailets/PerRecipientRateLimit.scala  |  6 +-
 .../transport/mailets/PerSenderRateLimit.scala     |  8 +--
 4 files changed, 39 insertions(+), 52 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
index 0751bb6a35..ead8e82b97 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
@@ -19,8 +19,6 @@
 
 package org.apache.james.transport.mailets
 
-import java.time.Duration
-import java.time.temporal.ChronoUnit
 import eu.timepit.refined.auto._
 import org.apache.james.rate.limiter.api.Increment.Increment
 import org.apache.james.rate.limiter.api.{AllowedQuantity, Increment, Rule, Rules}
@@ -28,6 +26,8 @@ import org.apache.james.transport.mailets.ConfigurationOps.{OptionOps, SizeOps}
 import org.apache.james.util.DurationParser
 import org.apache.mailet.{Mail, MailetConfig}
 
+import java.time.Duration
+import java.time.temporal.ChronoUnit
 import scala.util.Try
 
 case class KeyPrefix(value: String)
@@ -36,6 +36,7 @@ object ConfigurationOps {
 
   implicit class OptionOps(mailetConfig: MailetConfig) {
     def getOptionalString(key: String): Option[String] = Option(mailetConfig.getInitParameter(key))
+
     def getOptionalLong(key: String): Option[Long] = Option(mailetConfig.getInitParameter(key)).map(_.toLong)
   }
 
@@ -48,62 +49,48 @@ object ConfigurationOps {
     def getOptionalSize(key: String): Option[org.apache.james.util.Size] = mailetConfig.getOptionalString(key)
       .map {
         case "" => throw new IllegalArgumentException(s"'$key' field cannot be empty if specified")
-        case s => s
+        case s  => s
       }
       .map(org.apache.james.util.Size.parse)
   }
 }
 
+object EntityType {
+  def extractRules(entityType: EntityType, duration: Duration, mailetConfig: MailetConfig): Option[Rules] = (entityType match {
+    case Count          => mailetConfig.getOptionalLong("count")
+    case RecipientsType => mailetConfig.getOptionalLong("recipients")
+    case Size           => mailetConfig.getOptionalSize("size").map(_.asBytes())
+    case TotalSize      => mailetConfig.getOptionalSize("totalSize").map(_.asBytes())
+  }).map(AllowedQuantity.liftOrThrow)
+    .map(quantity => Rules(Seq(Rule(quantity, duration))))
 
-sealed trait EntityType {
-  def asString(): String
-
-  def extractQuantity(mail: Mail): Option[Increment]
+  def extractQuantity(entityType: EntityType, mail: Mail): Option[Increment] = entityType match {
+    case Count          => Some(1)
+    case RecipientsType => Some(Increment.liftOrThrow(mail.getRecipients.size()))
+    case Size           => Some(Increment.liftOrThrow(mail.getMessageSize.toInt))
+    case TotalSize      =>
+      Try(Math.multiplyExact(mail.getMessageSize.toInt, mail.getRecipients.size()))
+        .map(Increment.liftOrThrow)
+        .toOption
+  }
+}
 
-  def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules]
+sealed trait EntityType {
+  def asString: String
 }
 
 case object Count extends EntityType {
-  override def asString(): String = "count"
-
-  override def extractQuantity(mail: Mail): Option[Increment] = Some(1)
-
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalLong("count")
-    .map(AllowedQuantity.liftOrThrow)
-    .map(quantity => Rules(Seq(Rule(quantity, duration))))
+  override val asString: String = "count"
 }
 
 case object RecipientsType extends EntityType {
-  override def asString(): String = "recipients"
-
-  override def extractQuantity(mail: Mail): Option[Increment] = Some(Increment.liftOrThrow(mail.getRecipients.size()))
-
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalLong("recipients")
-    .map(AllowedQuantity.liftOrThrow)
-    .map(quantity => Rules(Seq(Rule(quantity, duration))))
+  override val asString: String = "recipients"
 }
 
 case object Size extends EntityType {
-  override def asString(): String = "size"
-
-  override def extractQuantity(mail: Mail): Option[Increment] = Some(Increment.liftOrThrow(mail.getMessageSize.toInt))
-
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalSize("size")
-    .map(_.asBytes())
-    .map(AllowedQuantity.liftOrThrow)
-    .map(quantity => Rules(Seq(Rule(quantity, duration))))
+  override val asString: String = "size"
 }
 
 case object TotalSize extends EntityType {
-  override def asString(): String = "totalSize"
-
-  override def extractQuantity(mail: Mail): Option[Increment] =
-    Try(Math.multiplyExact(mail.getMessageSize.toInt, mail.getRecipients.size()))
-      .map(Increment.liftOrThrow)
-      .toOption
-
-  override def extractRules(duration: Duration, mailetConfig: MailetConfig): Option[Rules] = mailetConfig.getOptionalSize("totalSize")
-    .map(_.asBytes())
-    .map(AllowedQuantity.liftOrThrow)
-    .map(quantity => Rules(Seq(Rule(quantity, duration))))
+  override val asString: String = "totalSize"
 }
\ No newline at end of file
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
index 0e1b3ecf7c..cf19976483 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
@@ -33,8 +33,8 @@ import reactor.core.scala.publisher.{SFlux, SMono}
 case class GlobalKey(keyPrefix: Option[KeyPrefix], entityType: EntityType) extends RateLimitingKey {
   val globalPrefix: String = "global"
 
-  override def asString(): String = keyPrefix.map(prefix => s"${prefix.value}_${entityType.asString()}_$globalPrefix}")
-    .getOrElse(s"${entityType.asString()}_$globalPrefix")
+  override def asString(): String = keyPrefix.map(prefix => s"${prefix.value}_${entityType.asString}_$globalPrefix}")
+    .getOrElse(s"${entityType.asString}_$globalPrefix")
 }
 
 case class GlobalRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Option[KeyPrefix], entityType: EntityType) {
@@ -42,7 +42,7 @@ case class GlobalRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Option
     val rateLimitingKey = GlobalKey(keyPrefix, entityType)
 
     rateLimiter.map(limiter =>
-      entityType.extractQuantity(mail)
+      EntityType.extractQuantity(entityType, mail)
         .map(increment => limiter.rateLimit(rateLimitingKey, increment))
         .getOrElse(SMono.just[RateLimitingResult](RateExceeded)))
       .getOrElse(SMono.just[RateLimitingResult](AcceptableRate))
@@ -143,7 +143,7 @@ class GlobalRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) extends
 
   private def createRateLimiter(rateLimiterFactory: RateLimiterFactory, entityType: EntityType, keyPrefix: Option[KeyPrefix],
                                 duration: Duration, precision: Option[Duration]): GlobalRateLimiter =
-    GlobalRateLimiter(rateLimiter = entityType.extractRules(duration, getMailetConfig)
+    GlobalRateLimiter(rateLimiter = EntityType.extractRules(entityType, duration, getMailetConfig)
       .map(rateLimiterFactory.withSpecification(_, precision)),
       keyPrefix = keyPrefix,
       entityType = entityType)
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
index 13b0f17fb7..86b7c94afb 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
@@ -40,7 +40,7 @@ import scala.util.Using
 
 case class PerRecipientRateLimiter(rateLimiter: RateLimiter, keyPrefix: Option[KeyPrefix], entityType: EntityType) {
   def rateLimit(recipient: MailAddress, mail: Mail): Publisher[RateLimitingResult] =
-    entityType.extractQuantity(mail)
+    EntityType.extractQuantity(entityType, mail)
       .map(increment => rateLimiter.rateLimit(RecipientKey(keyPrefix, entityType, recipient), increment))
       .getOrElse(SMono.just[RateLimitingResult](RateExceeded))
 }
@@ -49,7 +49,7 @@ case class RecipientKey(keyPrefix: Option[KeyPrefix], entityType: EntityType, ma
   override def asString(): String = s"${
     keyPrefix.map(prefix => prefix.value + "_")
       .getOrElse("")
-  }${entityType.asString()}_${mailAddress.asString()}"
+  }${entityType.asString}_${mailAddress.asString()}"
 }
 
 /**
@@ -135,7 +135,7 @@ class PerRecipientRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) ex
 
   private def createRateLimiter(entityType: EntityType, duration: Duration, precision: Option[Duration],
                                 rateLimiterFactory: RateLimiterFactory, keyPrefix: Option[KeyPrefix]): Option[PerRecipientRateLimiter] =
-    entityType.extractRules(duration, getMailetConfig)
+    EntityType.extractRules(entityType, duration, getMailetConfig)
       .map(rateLimiterFactory.withSpecification(_, precision))
       .map(PerRecipientRateLimiter(_, keyPrefix, entityType))
 
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
index c48831d9a9..fcd5b8a329 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
@@ -38,7 +38,7 @@ case class PerSenderRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Opt
     val rateLimitingKey = SenderKey(keyPrefix, entityType, sender)
 
     rateLimiter.map(limiter =>
-      entityType.extractQuantity(mail)
+      EntityType.extractQuantity(entityType, mail)
         .map(increment => limiter.rateLimit(rateLimitingKey, increment))
         .getOrElse(SMono.just[RateLimitingResult](RateExceeded)))
       .getOrElse(SMono.just[RateLimitingResult](AcceptableRate))
@@ -46,8 +46,8 @@ case class PerSenderRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Opt
 }
 
 case class SenderKey(keyPrefix: Option[KeyPrefix], entityType: EntityType, mailAddress: MailAddress) extends RateLimitingKey {
-  override def asString(): String = keyPrefix.map(prefix => s"${prefix.value}_${entityType.asString()}_${mailAddress.asString()}")
-    .getOrElse(s"${entityType.asString()}_${mailAddress.asString()}")
+  override def asString(): String = keyPrefix.map(prefix => s"${prefix.value}_${entityType.asString}_${mailAddress.asString()}")
+    .getOrElse(s"${entityType.asString}_${mailAddress.asString()}")
 }
 
 /**
@@ -150,7 +150,7 @@ class PerSenderRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) exten
 
   private def createRateLimiter(rateLimiterFactory: RateLimiterFactory, entityType: EntityType, keyPrefix: Option[KeyPrefix],
                                 duration: Duration, precision: Option[Duration]): PerSenderRateLimiter =
-    PerSenderRateLimiter(rateLimiter = entityType.extractRules(duration, getMailetConfig)
+    PerSenderRateLimiter(rateLimiter = EntityType.extractRules(entityType, duration, getMailetConfig)
       .map(rateLimiterFactory.withSpecification(_, precision)),
       keyPrefix = keyPrefix,
       entityType = entityType)


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


[james-project] 09/09: Rename RecipientType to Recipient

Posted by bt...@apache.org.
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 76b0050f2c0e3a73b7192b2ef1854a4147904fbf
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Sat Feb 25 08:40:55 2023 +0100

    Rename RecipientType to Recipient
---
 .../org/apache/james/transport/mailets/EntityType.scala    | 14 +++++++-------
 .../apache/james/transport/mailets/GlobalRateLimit.scala   |  2 +-
 .../james/transport/mailets/PerSenderRateLimit.scala       |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
index a93bfb53cc..58552e705b 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
@@ -62,20 +62,20 @@ object EntityType {
   }
 
   def extractRules(entityType: EntityType, duration: Duration, mailetConfig: MailetConfig): Option[Rules] = (entityType match {
-    case Count          => mailetConfig.getOptionalLong("count")
-    case RecipientsType => mailetConfig.getOptionalLong("recipients")
-    case Size           => mailetConfig.getOptionalSize("size").map(_.asBytes())
+    case Count      => mailetConfig.getOptionalLong("count")
+    case Recipients => mailetConfig.getOptionalLong("recipients")
+    case Size       => mailetConfig.getOptionalSize("size").map(_.asBytes())
     case TotalSize      => mailetConfig.getOptionalSize("totalSize").map(_.asBytes())
   }).map(AllowedQuantity.validate(_).orThrow(s"invalid quantity for ${entityType.asString}"))
     .map(quantity => Rules(Seq(Rule(quantity, duration))))
 
   def extractQuantity(entityType: EntityType, mail: Mail): Option[Increment] = entityType match {
-    case Count          => Some(1)
-    case RecipientsType =>
+    case Count      => Some(1)
+    case Recipients =>
       Some(Increment
         .validate(mail.getRecipients.size())
         .orThrow(s"invalid quantity for ${entityType.asString}"))
-    case Size           =>
+    case Size       =>
       Some(Increment
         .validate(mail.getMessageSize.toInt)
         .orThrow(s"invalid quantity for ${entityType.asString}"))
@@ -94,7 +94,7 @@ case object Count extends EntityType {
   override val asString: String = "count"
 }
 
-case object RecipientsType extends EntityType {
+case object Recipients extends EntityType {
   override val asString: String = "recipients"
 }
 
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
index 7ef7bfec51..982b2cb516 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
@@ -126,7 +126,7 @@ class GlobalRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) extends
     def globalRateLimiter(entityType: EntityType): GlobalRateLimiter = createRateLimiter(rateLimiterFactory, entityType, keyPrefix, duration, precision)
 
     countRateLimiter = globalRateLimiter(Count)
-    recipientsRateLimiter = globalRateLimiter(RecipientsType)
+    recipientsRateLimiter = globalRateLimiter(Recipients)
     sizeRateLimiter = globalRateLimiter(Size)
     totalSizeRateLimiter = globalRateLimiter(TotalSize)
   }
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
index fcd5b8a329..ee29406344 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerSenderRateLimit.scala
@@ -118,7 +118,7 @@ class PerSenderRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) exten
     def perSenderRateLimiter(entityType: EntityType): PerSenderRateLimiter = createRateLimiter(rateLimiterFactory, entityType, keyPrefix, duration, precision)
 
     countRateLimiter = perSenderRateLimiter(Count)
-    recipientsRateLimiter = perSenderRateLimiter(RecipientsType)
+    recipientsRateLimiter = perSenderRateLimiter(Recipients)
     sizeRateLimiter = perSenderRateLimiter(Size)
     totalSizeRateLimiter = perSenderRateLimiter(TotalSize)
   }


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


[james-project] 02/09: Simplify PerRecipientRateLimit init

Posted by bt...@apache.org.
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 9ba4f24b98d8608c296dcd37c151ac076509cbf5
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Thu Feb 9 21:41:05 2023 +0100

    Simplify PerRecipientRateLimit init
---
 .../scala/org/apache/james/transport/mailets/EntityType.scala |  8 ++++++--
 .../james/transport/mailets/PerRecipientRateLimit.scala       | 11 ++++-------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
index 4fbbebd009..cf9d87b979 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/EntityType.scala
@@ -33,11 +33,15 @@ import scala.util.Try
 case class KeyPrefix(value: String)
 
 object ConfigurationOps {
+
+  implicit class OptionOps(mailetConfig: MailetConfig) {
+    def getOptionalString(key: String): Option[String] = Option(mailetConfig.getInitParameter(key))
+  }
+
   implicit class DurationOps(mailetConfig: MailetConfig) {
-    def getDuration(key: String): Option[Duration] = Option(mailetConfig.getInitParameter(key))
+    def getDuration(key: String): Option[Duration] = mailetConfig.getOptionalString(key)
       .map(string => DurationParser.parse(string, ChronoUnit.SECONDS))
   }
-
 }
 
 
diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
index 0e0a4b16a9..13b0f17fb7 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/PerRecipientRateLimit.scala
@@ -28,7 +28,7 @@ import javax.inject.Inject
 import org.apache.james.core.MailAddress
 import org.apache.james.lifecycle.api.LifecycleUtil
 import org.apache.james.rate.limiter.api.{AcceptableRate, RateExceeded, RateLimiter, RateLimiterFactory, RateLimitingKey, RateLimitingResult}
-import org.apache.james.transport.mailets.ConfigurationOps.DurationOps
+import org.apache.james.transport.mailets.ConfigurationOps.{DurationOps, OptionOps}
 import org.apache.james.util.ReactorUtils.DEFAULT_CONCURRENCY
 import org.apache.mailet.base.GenericMailet
 import org.apache.mailet.{Mail, ProcessingState}
@@ -100,15 +100,12 @@ class PerRecipientRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) ex
   override def init(): Unit = {
     val duration: Duration = parseDuration()
     val precision: Option[Duration] = getMailetConfig.getDuration("precision")
-    val keyPrefix: Option[KeyPrefix] = Option(getInitParameter("keyPrefix")).map(KeyPrefix)
-    exceededProcessor = getInitParameter("exceededProcessor", Mail.ERROR)
+    val keyPrefix: Option[KeyPrefix] = getMailetConfig.getOptionalString("keyPrefix").map(KeyPrefix)
+    exceededProcessor = getMailetConfig.getOptionalString("exceededProcessor").getOrElse(Mail.ERROR)
 
     def perRecipientRateLimiter(entityType: EntityType): Option[PerRecipientRateLimiter] = createRateLimiter(entityType, duration, precision, rateLimiterFactory, keyPrefix)
 
-    rateLimiters = Seq(perRecipientRateLimiter(Size),
-      perRecipientRateLimiter(Count))
-      .filter(limiter => limiter.isDefined)
-      .map(limiter => limiter.get)
+    rateLimiters = Seq(Size, Count).flatMap(perRecipientRateLimiter)
   }
 
   override def service(mail: Mail): Unit = {


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


[james-project] 07/09: When we don't get any limiter, don't build a global rate limiter

Posted by bt...@apache.org.
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 a784fa5c0d904b29c8e2224bf88af43b877cd802
Author: Matthieu Baechler <ma...@baechler-craftsmanship.fr>
AuthorDate: Fri Feb 10 09:16:52 2023 +0100

    When we don't get any limiter, don't build a global rate limiter
---
 .../james/transport/mailets/GlobalRateLimit.scala  | 30 ++++++++++++++--------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
index c446f48875..7ef7bfec51 100644
--- a/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
+++ b/server/mailet/rate-limiter/src/main/scala/org/apache/james/transport/mailets/GlobalRateLimit.scala
@@ -37,16 +37,21 @@ case class GlobalKey(keyPrefix: Option[KeyPrefix], entityType: EntityType) exten
   }
 }
 
-class GlobalRateLimiter(rateLimiter: Option[RateLimiter], keyPrefix: Option[KeyPrefix], entityType: EntityType) {
-  def rateLimit(mail: Mail): Publisher[RateLimitingResult] = {
+trait GlobalRateLimiter {
+  def rateLimit(mail: Mail): Publisher[RateLimitingResult]
+}
+
+object GlobalRateLimiter {
+  def fromRateLimiter(rateLimiter: RateLimiter, keyPrefix: Option[KeyPrefix], entityType: EntityType): GlobalRateLimiter = {
     val rateLimitingKey = GlobalKey(keyPrefix, entityType)
 
-    rateLimiter.map(limiter =>
+    mail =>
       EntityType.extractQuantity(entityType, mail)
-        .map(increment => limiter.rateLimit(rateLimitingKey, increment))
-        .getOrElse(SMono.just[RateLimitingResult](RateExceeded)))
-      .getOrElse(SMono.just[RateLimitingResult](AcceptableRate))
+        .map(increment => rateLimiter.rateLimit(rateLimitingKey, increment))
+        .getOrElse(SMono.just[RateLimitingResult](RateExceeded))
   }
+
+  val acceptAll: GlobalRateLimiter = mail => SMono.just[RateLimitingResult](AcceptableRate)
 }
 
 /**
@@ -141,12 +146,17 @@ class GlobalRateLimit @Inject()(rateLimiterFactory: RateLimiterFactory) extends
     }
   }
 
+
   private def createRateLimiter(rateLimiterFactory: RateLimiterFactory, entityType: EntityType, keyPrefix: Option[KeyPrefix],
                                 duration: Duration, precision: Option[Duration]): GlobalRateLimiter =
-    new GlobalRateLimiter(rateLimiter = EntityType.extractRules(entityType, duration, getMailetConfig)
-      .map(rateLimiterFactory.withSpecification(_, precision)),
-      keyPrefix = keyPrefix,
-      entityType = entityType)
+    EntityType.extractRules(entityType, duration, getMailetConfig)
+      .map(rateLimiterFactory.withSpecification(_, precision))
+      .map(rateLimiter =>
+        GlobalRateLimiter.fromRateLimiter(
+          rateLimiter = rateLimiter,
+          keyPrefix = keyPrefix,
+          entityType = entityType))
+      .getOrElse(GlobalRateLimiter.acceptAll)
 
 
   override def requiredProcessingState(): util.Collection[ProcessingState] = ImmutableList.of(new ProcessingState(exceededProcessor))


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