Looking for Computer Science & Information Technology online
courses ?
Check my new web site: https://www.yesik.it !
Apache James est un serveur de courrier électronique écrit en Java. Mais c'est aussi un container de mailet. Qu'est-ce que ça veut dire? Simplement que James peut charger des classes Java que vous avez écrites pour associer un traitement personnalisé à la réception d'un courrier électronique. Autrement dit, une mailet est l'équivalent pour le mail d'une servlet pour les requêtes web. Tout un monde de possibilités s'ouvre à nous, non? Dans cet article, nous allons voir comment créer une mailet et configurer Apache James pour l'utiliser.
Sommaire
Les bases
Dans le principe, ajouter une nouvelle mailet à James se fait en 3 étapes:
- Tout d'abord, il faut coder et compiler la mailet;
- Ensuite, il faut la déployer pour que James puisse la trouver;
- Enfin il faut configurer James pour qu'il sache quand et sur quel mail l'invoquer.
Codage
Concrètement, une mailet pour Apache James est simplement une classe qui met en oeuvre l'interface org.apache.mailet.Mailet. Celle-ci contient un certain nombre de méthodes détaillées dans la documentation de James (voir javadoc). Dans l'exemple ci-dessous, je me contente du strict minimum en ne mettant réellement en oeuvre que la méthode service. Et encore, de manière triviale! Les autres méthodes ne sont définies que pour se conformer à l'interface – mais dans cet exemple, elles ne font rien:
package fr.chicoree.mailets; import javax.mail.MessagingException; import org.apache.mailet.Mail; import org.apache.mailet.Mailet; import org.apache.mailet.MailetConfig; public class MyMailet implements Mailet { @Override public void destroy() { } @Override public MailetConfig getMailetConfig() { return null; } @Override public String getMailetInfo() { return null; } @Override public void init(MailetConfig config) throws MessagingException { } @Override public void service(Mail mail) throws MessagingException { System.err.println("reveiced " + mail.getMessage().getSubject()); } }
Pour compiler cette classe, vous aurez besoin des bibliothèques mailet-api-x.y.jar et mail-x.y.z.jar correspondant à la version de James que vous avez installée. Celles-ci sont fournies avec James dans le fichier /path/to/james/apps/james.sar. Il faudra donc les extraire et les placer dans votre CLASSPATH pour pouvoir compiler votre mailet:
sh$ jar xvf /path/to/james-2.3.1/apps/james.sar SAR-INF/lib created: SAR-INF/lib/ inflated: SAR-INF/lib/james-2.3.1.jar inflated: SAR-INF/lib/mailet-2.3.jar inflated: SAR-INF/lib/mailet-api-2.3.jar inflated: SAR-INF/lib/activation-1.1.1.jar inflated: SAR-INF/lib/bcmail-jdk14-129-workaround.jar ... inflated: SAR-INF/lib/jakarta-oro-2.0.8.jar inflated: SAR-INF/lib/mail-1.4.1.jar sh$ javac -cp .:SAR-INF/lib/mailet-api-2.3.jar:SAR-INF/lib/mail-1.4.1.jar \ fr/chicoree/mailets/MyMailet.java sh$ jar cf MyMailet.jar fr/chicoree/mailets/MyMailet.class
Déploiement
Si coder et compiler la mailet est la première étape. La seconde est de la déployer en copiant la mailet compilée dans le répertoire adéquat:
sh$ cd /path/to/james-2.3.1/apps/james sh$ mkdir SAR-INF/lib # Si nécessaire sh$ cp /path/to/mymailet.jar SAR-INF/lib
Configuration
Enfin, il faut configurer James pour qu'il sache où trouver notre mailet et à quel moment l'invoquer. Cela se fait dans le fichier de configuration SAR-INF/config.xml. Vous devrez y localiser les éléments suivants:
- mailetpackages
- Qui indique à James les packages Java qui contient les mailets utilisées par cette configuration de James
- spoolmanager
- qui définit l'ordre et la nature des traitements appliqués par James aux courriers entrants. C'est en quelque sorte là que se code la logique de votre serveur de courrier. Pour faciliter l'organisation des traitements, ceux-ci sont groupés en processeurs (processor). C'est un peu l'équivalent dans James d'une fonction ou d'une procédure dans un langage structuré. Plus formellement, les processeurs sont les états dans l'automate état-transition qui représente les étapes par lesquelles peut passer un message entrant. Le point de départ de ce graphe est le processeur nommé root (<processor name='root'><!-- ... ---></processor>).
Ainsi, pour exécuter notre mailet sur tous les courriers entrants, nous pouvons utiliser la configuration suivante:
<!-- Set the Java packages from which to load mailets and matchers -->
<mailetpackages>
<mailetpackage>org.apache.james.transport.mailets</mailetpackage>
<mailetpackage>org.apache.james.transport.mailets.smime</mailetpackage>
<mailetpackage>fr.chicoree.mailets</mailetpackage>
</mailetpackages>
<!-- The James Spool Manager block -->
<!-- -->
<!-- This block is responsible for processing messages on the spool. -->
<spoolmanager>
<!-- ... --->
<processor name="root">
<mailet match="All" class="MyMailet" />
<!-- This mailet redirects mail for the user 'postmaster' at any local domain to -->
<!-- the postmaster address specified for the server. The postmaster address -->
<!-- is required by rfc822. Do not remove this mailet unless you are meeting -->
<!-- this requirement through other means (e.g. a XML/JDBCVirtualUserTable mailet) -->
<mailet match="All" class="PostmasterAlias"/>
Comme après chaque modification de la configuration, reste à (re)lancer James:
sh$ sudo JAVA_HOME=$JAVA_HOME bin/run.sh Using PHOENIX_HOME: /home/sylvain/james-2.3.1 Using PHOENIX_TMPDIR: /home/sylvain/james-2.3.1/temp Using JAVA_HOME: /usr/lib/jvm/java-6-sun-1.6.0.12 Running Phoenix: Phoenix 4.2 James Mail Server 2.3.1 Remote Manager Service started plain:4555 POP3 Service started plain:110 SMTP Service started plain:25 NNTP Service started plain:119 FetchMail Disabled
Et pour tester, il suffit d'envoyer un mail via notre serveur de messagerie. Par exemple, si vous envoyez un message avec Hello mailet en sujet en utilisant James comme MTA (Mail Transfert Agent – Logiciel de transfert de courrier électronique
(plus)) vous devriez voir apparaître le message généré par notre mailet sur la console de James:
James Mail Server 2.3.1
Remote Manager Service started plain:4555
POP3 Service started plain:110
SMTP Service started plain:25
NNTP Service started plain:119
FetchMail Disabled
reveiced Hello mailet
Mailet, matchers et processors
Dans la configuration actuelle, pour activer notre mailet, il suffit d'envoyer un mail via James. Il n'est absolument pas nécessaire que James gère le compte mail du destinataire. Autrement dit, tout mail passant par notre serveur de messagerie sera traité par notre mailet.
La raison pour laquelle James se compte ainsi, c'est que nous avons configuré notre mailet dans le processeur root et avec le matcher All:
<!-- ... --> <processor name="root"> <mailet match="All" class="MyMailet" />
Nous l'avons déjà dit, le processeur dans James est simplement un groupe de mailets à activer quand un message arrive. Le matcher quand à lui permet de filtrer les mails auxquels s'appliquent chaque mailet. Comme son nom l'indique, le matcher All permet d'appliquer une mailet à tous les mails traités par le processeur actuel.

Remarque:
Tout comme pour la maillet, le matcher est désigné par un nom de classe Java. Vous pouvez donc si vous le désirez créer vos propres matchers pour filtrer certains messages spécifiques à votre domaine.
La mailet ToProcesseur est importante à connaître, puisque c'est elle qui permet de propager un message d'un processeur à l'autre. Autrement dit, c'est grâce à cette mailet que le message navigue dans le graphe des processeurs définis par la configuration de James.
A titre d'illustration, nous pourrions appliquer notre mailet uniquement aux messages destinés à un utilisateur local en remplaçant le matcher dans la configuration par RecipientIsLocal:
<processor name="root">
<mailet match="RecipientIsLocal" class="MyMailet" />
De la même manière, selon l'utilisation de notre mailet, il serait sans doute également plus intéressant de ne l'appliquer qu'aux messages qui ont déjà été filtrés contre le spam et les virus. En suivant la configuration de James, vous constaterez que les messages bon à transporter se retrouvent traités pas le processeur transport. On pourrait donc déplacer l'activation de notre mailet dans ce processeur:
<processor name="transport">
<mailet match="RecipientIsLocal" class="MyMailet" />
Conclusion
A l'issue de cet article, vous devriez vous être rendu compte, qu'il n'est pas très compliqué de modifier James pour traiter les messages entrant de manière automatisée. Nous n'avons bien sûr pas fait le tour en détail des possibilités de James. Mais au moins devriez-vous avoir une vue d'ensemble suffisante pour pouvoir vous lancer confiant dans l'écriture de votre première mailet utile!
Ressources
- (en) http://james.apache.org/server/2.3.2/installation_instructions.html – Installation de James 2.3.2
- (en) http://james.apache.org/mailet/api/index.html – La documentation de l'API mailet
- (en) http://james.apache.org/server/2.3.2/apidocs/index.html – Javadoc de l'API JAmes Server 2.3.2
- (en) http://james.apache.org/server/2.3.1/custom_mailet.html – Comment écrire une mailet et configurer James Server pour l'utiliser