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 purpose

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 elsewhere).

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 :

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

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

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

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

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

Type: User Alias
Sample config: bob@foo -> joe@bar
Cases:
bob@foo -> joe@bar
joe@bar -> joe@bar
john@poney -> john@poney
{code}

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

{code}
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));
}
{code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
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