james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marco Beelen <ja...@mcbeelen.net>
Subject [ GSoC - failfast SMTP ] Architecture and suggestion
Date Tue, 12 Jul 2005 23:58:10 GMT
Hello Anagha ( and of course many others ),

Although I'm not an active developer for james yet ( besides being an 
active user, which already is the case and very satisfied  one ), I've 
been monitoring the mailing-list for some while and do have some ideas 
about the architecture of the product.

Your design for the fail-fast SMTPServer triggered me to post my ideas. 
I'll start by some general outline of my vision about the architecture 
and finish with a suggestion for the Summer of Code proposal.

Juan Carlos Murillo posted a message about James as a distributed 
enterprise application suite, which I agree upon.
( http://www.mail-archive.com/server-dev@james.apache.org/msg04325.html )

I think implementations for a handler of a network protocol ( SMTP, 
POP3, IMAP and NNTP ) should be loosly coupled from spoolmanager and 
user- or mail-repositories. Access to the spoolmanager, 
user-repositories and mailrepositories should be able to be done eighter 
locally within the same JVM ( single-machine-configuration ) of remotely 
( possible using JMS ) in a 'clustered enterprice environment'.
In order to make this work, we would have to seperate the front-end ( 
the actual handling of the network protocol ) from the back-end ( 
reading and writing to JamesConfiguration, UserRepositories, 
MailRepositories and the SpoolManager ).  During the startup of a Server 
it should be configured on how to access the backend. Dependancy 
Injection ( by usage of Spring ) seems like a logical solution for that 

By doing this you could concentrate on the actual SMTP-protocol when 
writing an implementating for a SMTPProtocolHandler and delegate 
backend-interaction to a implementation of some 'JamesBackendInterface'.

This could simplify the implementation of the failfast SMTP-server, 
especially since your design for the ProtocolHandler looks very simular 
to the design of MINA.

"MINA is a network application framework to resolve all the issues 
concerned with implementing any protocol stack in Java without 
sacrificing performance nor scalability." MINA has been developed as a 
sub-project of the directory project of the ASF. ( I consider this as an 
indication of the quality of your design. )

Therefor I would like to suggest that you take a look at Mina and 
consider it as the basis for your implementation.

This is something which should be agreed upon by you and the active 

Suggested materials for reading about MINA:

I know this is properably a fuzzy description about my ideas for the 
architecture and I'm willing to clearify any questions about it.
I'll start working on some UML-diagrams to improve the 'readibility' and 
put those up for discussion in a seperate threat.

With kind regards,
    Marco Beelen
    The Netherlands ( GMT +1:00 )

Anagha Mudigonda wrote:

>I did a little more work on the design and fixed some
>mistakes. Attached is an updated design.
>awaiting comments ...
>-- anagha
>--- Danny Angus <Danny_Angus@slc.co.uk> wrote:
>Introduction:The redesign of the SMTP protocol handler has the following design goals
>      - to enable in-protocol handling 
>	- to have enough flexibility to implement SMTP protocol extensions without changing protocol
handling code.
>The new framework is designed to address these. The framework contains the following classes
>      - CommandHandler
>      - ConnectionHandler
>      - SMTPSession
>      - SMTPProtocolHandler 
>      - SMTPOutputStream
>      - SMTPInputStream
>      - an XML configuration file.
>The main change: 
>	- Introduction of SMTPSession as a new interface.
>	- Things are more CommandHandler centric. The command handler has access to the SMTPSession.
So, the command handler             	   now has freedom to close a message or even close a
session. But the SMTPSession interface is implemented in the 	   james core code. 
>Class ConnectionHandler
>1. Registers to handle a connection
>2. Registers to handle a message 
>interface ConnectionHandler
>void init(String configStr); 
>void processConnection(String  local_hostname, int local_port, String remote_hostname,
int remote_port); 
>void setSMTPSession(SMTPSession session);
>void processMessage(Mail Obj); 
>Class CommandHandler
>A Commandhandler class
>1. Registers to handle a command ( may process or validate the command arguments)
>2. Registers to handle a message (validate message or modify message header or body)(this
is needed for situations like SPF failure, where the headers are updated if SPF fails.)
>interface CommandHandler
> void init(String configStr); 
> void processCommand(String cmdString); 
> void setSMTPSession(SMTPSession session);
> void processMessage(Mail Obj); 
>Description: There can be more than one command handler registered for a command. 
>CommandHandlers can be registered to validate commands or  modify message.
>CommandHandler's *process* methods can trigger events like message start , message end
and message abort
>and session end, session abort.
>Class SMTPSession
>The SMTP protocol session maintains the state information and ensures that 
>the commands are executed in proper order. Also it provides controlled
>access to I/O streams.
>The SMTP session can be in one of the 4 states:
>1. SESSION_START ( as soon as the client connects to server)
>2. SESSION_END ( as soon as the client Sends QUIT command or closes connection)
>3. MESSAGE_START ( as soon as the client issues MAIL FROM command)
>4. MESSAGE_END ( as soon as the client sends message after DATA command)
>These states are more like triggers. For instance, all the message handlers get triggered
>interface SMTPSession
> //Write Response
> void WriteResponse(String respString);
>//Register connection handlers
>void registerConnectionHandler(ConnectionHandler connHandler);
>//Register connectionhandlers to handle Message
>void registerMessageHandler(ConnectionHandler connHandler);
> //Register commandhandlers to command
> void registerCommandHandler(String cmdPrefix, CommandHandler cmdHandler);
> //Register commandhandlers to handle Message
> void registerMessageHandler(CommandHandler cmdHandler);
> //Command sequence handling
> void addCommandSequenceMap(string command, String[] predecessorCmds, string failMessage);
> bool isCommandAllowed(String cmdString);
> //State information
> String getSender();
> String[] getRecepients();
> String setSender(String sender);
> String addRecepient(String recepient);
> String addRecepient(String[] recepients);
> String removeRecepient(String[] recepient);
> String removeRecepient(String recepient);
> //Message state modifier
> void startMessage(); 
> void endMessage(); 
> void abortMessage();
> //Message state modifier
> void endSession();
> void startSession();
> void abortSession();
> void reset();
> SMTPInputStream getInputStream(); // object with no permission to close stream  
> SMTPOutputStream getOutputStream(); // Output stream object with no permission to close
>SMTPSession is per connection and is accessible to all commandhandlers.
>If a command handler needs to modify the message, it registers with SMTPSession object.
>And SMTPsession object registers after the message is received passes the message to 
>all the registered commandhandlers for processing.
>class SMTPProtocolHandler
>class SMTPProtocolHandler implements SMTPSession
> //load all handlers and configure these
> //configure the command sequence
> //wait for SMTP connection
> //Create session state object
> //check if the command is allowed else respond with the failure message 
> //then loop thru the command handlers registered with the command and process the command
> //When Message end is triggered, call all the handlers registered for the message
>XML Configuration
>   <smtpserver enabled="true">
>      <!-- port 25 is the well-known/IANA registered port for SMTP -->
>      <port>25</port>
>      <!-- NEW CONFIGURATION -->
>      <Protocolhandler class="org.apache.james.SMTPHandler">
>         <Session class=org.apache.james.SMTPSession>
>         <command name="MAIL" commandSequence="HELO,EHLO"/>
>         <command name="RCPT" commandSequence="RCPT"/>
>         <event sessionStartCommand=""/>
>         <event sessionEndCommand="QUIT"/>
>         <event MessageBeginCommand="MAIL"/>
>         <event MessageEndCommand="DATA"/>
>         </Session>
>         <!-- registers with Protocol handler to handle "MAIL" command -->
>         <CommandHandler class="org.apache.james.MAILCommandHandler">
>          config..
>         </CommandHandler>
>         <!-- registers with protocol handler to handle "MAIL" command 
>              also registers with protocol handler to handle Message (SPFhandler adds
a SPF details into Message header)
>         -->
>         <CommandHandler name="SPFHandler">
>          config...
>         </CommandHandler>
>         <CommandHandler name="org.apache.james.RCPTCommandHandler">
>          config
>         </CommandHandler>
>         <CommandHandler name="RecepientValidator">
>          config
>         </CommandHandler>
>      </protocolhandler>
>   </smtpserver>
>Since the classes are loaded based on XML configuration, the default handlers can be replaced
by custom handlers whenever needed.
>Ease of use of the framework
>1. New commands can be added (for eg: STARTTLS)
>   Add new command handlers and modifiying the config to include new command sequence.
>2. New Validations (SPF validation)
>   Add a new command handler.
>To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
>For additional commands, e-mail: server-dev-help@james.apache.org

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

View raw message