Tung TRAN created JAMES-3693:
--------------------------------

             Summary: Email rate limiting
                 Key: JAMES-3693
                 URL: https://issues.apache.org/jira/browse/JAMES-3693
             Project: James Server
          Issue Type: New Feature
            Reporter: Tung TRAN


h3. Why

 
Rate limiting is one of the common features. Examples: SaaS is one 
[https://www.fastmail.help/hc/en-us/articles/1500000277382-Account-limits#sending/receiving],
 [https://support.google.com/mail/answer/22839]
 
They limit how many emails you can send/receive from/to each email account over 
a given period of time.
We believe the rate-limiting will help James has more control of the resource 
and easy to dynamic config the user policy. It also complements the storage 
quota.
 
h3. How

- Create a new sub maven module for this extension. This extension will be 
dropped by default in one James installation (not of a runtime dependency)

- The rate limit will have 2 criteria: number of emails and total size of emails

- Create 3 mailets:
 * PerSenderRateLimit is per sender
 * PerRecipientRateLimit is per recipient
 * GlobalRateLimit for everyone

 
The mailetcontainer configuration will look like:
{code:xml}
 
<mailet matcher="All" class="PerSenderRateLimit">
(<redisURL>...</redisURL> + creds?)
<!-- Appended before the type (count/size) and the sender mail address to store 
the current rate in Redis -->
<redisKeyPrefix>xxx</redisKeyPrefix>
<period>1hour</period>
<count>100<count>
<size>1GB</size>
</mailet>
 
<mailet matcher="All" class="PerRecipientRateLimit">
(<redisURL>...</redisURL> + creds?)
<!-- Appended before the type (count/size) and the sender mail address to store 
the current rate in Redis -->
<redisKeyPrefix>xxx</redisKeyPrefix>
<period>1hour</period>
<count>100<count>
<size>1GB</size>
</mailet>
 
<mailet matcher="All" class="GlobalRateLimit">
(<redisURL>...</redisURL> + creds?)
<!-- Appended before the type (count/size) and the sender mail address to store 
the current rate in Redis -->
<redisKeyPrefix>xxx</redisKeyPrefix>
<period>1hour</period>
<count>100<count>
<recipients>100<recipients>
<size>1GB</size>
<sizeForAllRecipients>5GB</sizeForAllRecipients>
<exceededProcessor>tooMuchMails</exceededProcessor>
</mailet> {code}
 

- Create an interface RateLimiter, which will evaluate the current rate limit 
and return whether the result is acceptable or exceeded.

- Create the implement InmemoryRateLimiter, which use guava-rate-limiter

- Create a configuration POJO RedisRateLimiterConfiguration(Duration period, 
URL redisServerURL).

- Create the implement RedisRateLimiter, which will use Redis to store the 
current rate of each email. Use [https://lettuce.io/] for the non-blocking 
Redis driver.

- Write the document such as a setup, and provide a mailetcontainer sample file.
h3. References
 - [https://www.baeldung.com/guava-rate-limiter]
 - [https://github.com/lettuce-io/lettuce-core#reactive-api]



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

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

Reply via email to