james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Matthieu Baechler (JIRA)" <server-...@james.apache.org>
Subject [jira] [Created] (JAMES-2380) RRT design discussion
Date Thu, 19 Apr 2018 14:57:00 GMT
Matthieu Baechler created JAMES-2380:

             Summary: RRT design discussion
                 Key: JAMES-2380
                 URL: https://issues.apache.org/jira/browse/JAMES-2380
             Project: James Server
          Issue Type: Improvement
            Reporter: Matthieu Baechler

We worked a lot on RecipientRewriteTable lately and everything is very complicated right now.

There are several interleaved concepts right now, that I'll try to explain here.

The goal of RecipientRewriteTable is to allow rewrite a Recipient to another one (or generate
and error).

Such rewrite is done with so-called Mapping(s) : a Mapping is a rule that given a User (==
recipient), generates either an error or new User(s).

At start, there were simple rule types :
* address mapping that allows to go from (for example) bob@foo to bob@bar
* regex mapping that allows to match a regex against the recipient mail address and output
a new one, optionally using matching groups
* domain mapping that allows to rewrite all users of a domain into users of another one
* error mapping that would prevent delivery to an given user

We recently added :
* group, like address mapping but allows to register several rewrite outputs
* forward, like group but using a different type allows to filter on the wanted type for administrative

Here are a list of design problems I see :

1. Error has probably nothing to do in the rewrite feature

It's very likely that error mapping is in fact the job of another mailet (and should be stored

2. we mix how we rewrite something with the original intent of the rule writer.

We could argue that every types of rewrite rules can be expressed by a matching regex and
a list of output expression.

If performance is a problem here, we could specialize rewriter like that :

Type: Domain Alias
Sample config: foo -> bar (could also be written *@foo -> *@bar)
bob@foo -> bob@bar
joe@foo -> joe@bar
john@poney -> john@poney

Type: Wildcard
Sample config: * -> foo@bar
bob@foo -> foo@bar
joe@foo -> foo@bar
john@poney -> foo@bar 

Type: UserWildcard
Sample config: bob@* -> joe@*
bob@foo -> joe@foo
bob@bar -> joe@bar
joe@foo -> joe@foo

Type: UserWildcard
Sample config: joe@* -> joe@bar
bob@foo -> bob@foo
joe@bar -> joe@bar
joe@foo -> joe@bar
john@poney -> john@poney 

Type: DomainWildcard
Sample config: *@foo -> joe@bar
bob@foo -> joe@bar
joe@foo -> joe@bar
john@poney -> john@poney 

Type: User Alias
Sample config: bob@foo -> joe@bar
bob@foo -> joe@bar
joe@bar -> joe@bar
john@poney -> john@poney

A good way to keep the user intent next to the rule definition would be to store such a structure

Mapping {
  intent: {
    type: "group",
    definition: {
      //type specific definition
  rule: {
    type: "Address",
    definition: {
      //type specific definition

Once we have such a structure, admin commands would very well add/modify/delete mappings based
on "intent" and the rewrite engine would only care about applying rewrite rules.

3. The process should be as simple as (pseudo-code) :

Input : Recipient

Stream<MailAddress> rewrite(MailAddress input, limitLoop = 10) {
  if (limitLoop <= 0) {
    throw new loopDetectedException();
  Rule rule = RRT.findFirstRuleFor(input);
  Stream<MailAddress> rewrittenRecipients = rule.rewrite(input);
  return rewrittenRecipients.flatMap(recipient -> rewrite(recipient, limitLoop - 1));

This message was sent by Atlassian JIRA

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

View raw message