FakeSMTP est un serveur SMTP.
On peut lui envoyer des e-mails mais il ne les transmet jamais aux destinataires.
Il les stocke dans un répertoire local sous forme de fichiers .eml
.
On l’utilise généralement en environnement de développement ou en test d’intégration.
Docker
Il existe plusieurs logiciels qui répondent au nom de FakeSMTP. Celui que j’utilise est développé par Gautier Mechling, en Java.
Le développement a commencé en 2011, jusqu’en 2015. Depuis, la maintenance est ralentie. Mais je ne pense pas que ça pose de problème. Il tourne bien sur un JDK 11, preuve qu’il vieillit bien.
Image Docker
Avant j’utilisais l’image munkyboy/fakesmtp
, mais elle fonctionne avec un JDK 7 et n’a jamais été mise à jour.
Depuis, je suis passé sur ghusta/fakesmtp
dont la dernière version tourne sur un JDK 11.
docker run --publish 127.0.0.1:2025:25 --detach ghusta/fakesmtp
Le conteneur fonctionne en root, mais je n’ai pas trouvé d’équivalent avec un user. |
Volume
Pour accéder aux fichiers .eml des messages, il faut monter un volume en répertoire local.
docker run --publish 127.0.0.1:2025:25 --volume /tmp/smtp:/var/mail --detach ghusta/fakesmtp
Docker Compose
smtp:
image: ghusta/fakesmtp
ports:
- "127.0.0.1:2025:25"
volumes:
- "/tmp/smtp:/var/mail"
Dans les tests
Ça peut aussi se démarrer avec Testcontainer pour des tests d’intégration automatisés.
GenericContainer<?> smtp = new GenericContainer<>("ghusta/fakesmtp")
.withExposedPorts(25);
smtp.start();
int smtpPort = smtp.getMappedPort(25);
Lecture des messages
Pour lire les fichiers eml, on peut utiliser l’API Jakarta Mail, anciennement _Java Mail.
La principipale classe est MimeMessage
, elle permet d’accéder aux données et métadonnées d’un message.
Pour avoir un tel objet, il faut ouvrir un IntputStream
sur le fichier .eml
et le passer en paramètre du contructeur.
InputStream is = Files.newInputStream(emlPath);
Session session = Session.getDefaultInstance(new Properties());
MimeMessage message = new MimeMessage(session, is);
// ...
-
-
parse()
-
getFrom(): Address[]
-
getReplyTo(): Address[]
-
getRecipients(Message.RecipientType type): Address[]
-
getSubject(): String
-
getContent(): Object
-
L’API standard n’étant pas très amicale, je préfère encapsuler l’objet dans un EmailWrapper
:
-
plutôt que de retourner des
Address
, je manipule desString
, -
les méthodes sont susceptibles de lever des
MessagingException
qui sont checked, -
le contenu peut être multipart qui doit être décortiqué.
Apache Commons Mail a une classe MimeMessageParser
qui facilite aussi la manipulation de MimeMessage
.
Cette classe a quand même un gros défaut, ses méthodes sont susceptibles de lever une Exception
, sans autre précision.
-
-
parse()
-
getFrom(): String
-
getReplyTo(): String
-
getTo(): List<Address>
-
getCc(): List<Address>
-
getBcc(): List<Address>
-
getSubject(): String
-
getHtmlContent(): String
-
getPlainContent(): String
-
Spring Framework a une classe MimeMessageHelper
qui facilite aussi la manipulation de MimeMessage
, mais qui est beaucoup plus orientée sur l’écriture d’un message que sur sa lecture.