You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by ma...@apache.org on 2023/02/22 20:14:01 UTC
[james-project] 04/08: Switch from OOP style to FP style
This is an automated email from the ASF dual-hosted git repository.
matthieu pushed a commit to branch refactorings-5
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 7a1e9f29e3fc0184f82f40120e39be2302c7fbcf
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 e579d361c8..c451f9c2a2 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
@@ -34,8 +34,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) {
@@ -43,7 +43,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))
@@ -142,7 +142,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