Am I naive in thinking I will be able to pull this off without coding my own generic mail handler, or deferring the mail stuff to syslog?
If you are using at least JavaMail 1.5.0, JakartaMail, or AngusMail, the MailHandler itself will connect to local address name on port 25 as user.name system property with a computed from and to address when no properties have been specified. If there is a mail transfer agent running that accepts the connection you can then configure rules on the MTA to forward and authenticate. Securing that MTA is the tricky part of this approach.
Bafflingly, there's no SMTP implementation out of the box. How is it not a basic feature?
I created an Angus Mail issue #110 WildFly support for MailHandler to provide out of the box support in Angus Mail 2.0.3 or newer. This change adds new methods to configure the mail properties via strings. Steps for setup are as follows:
- Determine the module name of the MailHandler. Start by verify the version Angus Mail in WildFly. The jar is located in
wildfly-29.0.1.Final/modules/system/layers/base/org/eclipse/angus/mail/main. If that version is angus-mail-2.0.3.jar or newer the module name is org.eclipse.angus.mail and you can continue to step 2 using this name. If the version is older then a new module must be created. Download latest jakarta.mail-api, jakarta.activation-api, angus-activation, and angus-mail jars. Start WildFly and connect the jbosscli. Using the 4 jars that were downloaded create a module named org.eclipse.angus.logging-mailhandler which will be used in the following steps. Here is an example:
module add --name=org.eclipse.angus.logging-mailhandler --resource-delimiter=; --resources=~/jaf-api/api/target/jakarta.activation-api-X.Y.Z.jar;~/mail/api/target/jakarta.mail-api-X.Y.Z.jar;~/angus-activation/activation-registry/target/angus-activation-X.Y.Z.jar;~/angus-mail/providers/angus-mail/target/angus-mail-X.Y.Z.jar --dependencies=jakarta.activation.api,jakarta.mail.api,org.eclipse.angus.activation,org.eclipse.angus.mail,org.jboss.modules,java.logging,org.jboss.logging
- Create spam and push filters to avoid flooding. Angus Mail ships with DurationFilter that can be installed to control the max rate emails can be generated. Assuming default MailHandler capacity of 1000 and at most one email per hour then use the following in the jbosscli (edit the module name if needed):
/subsystem=logging/filter=SPAM_FILTER:add(module=org.eclipse.angus.logging-mailhandler, class=org.eclipse.angus.mail.util.logging.DurationFilter, properties={records=1000,durationMillis=3600000})
/subsystem=logging/filter=PUSH_FILTER:add(module=org.eclipse.angus.logging-mailhandler, class=org.eclipse.angus.mail.util.logging.DurationFilter, properties={records=1,durationMillis=3600000})
- Create MailHandler as CustomHandler. In the jbosscli (edit the module name if needed):
/subsystem=logging/custom-handler="MAIL":add(class="org.eclipse.angus.mail.util.logging.MailHandler", module="org.eclipse.angus.logging-mailhandler", level="WARNING", formatter="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n", encoding="UTF-8", filter-spec="SPAM_FILTER", properties={"pushLevel"=>"ALL","pushFilter"=>"PUSH_FILTER", "mailEntries"=>"mail.smtp.port:25#!mail.host:localhost#!mail.from:wildfly@localhost#!mail.to:support@localhost#!mail.smtp.connectiontimeout:15000#!mail.smtp.timeout:45000#!verify:local"})
Consult the AngusMail API for additional mail entries. This configuration will buffer records when PUSH_FILTER rate is exceeded and will drop records when the SPAM_FILTER rate is exceeded.
- Optionally, wrap the MailHandler in an AsyncHandler. In the jbosscli (edit the module name if needed):
/subsystem=logging/async-handler="ASYNC_MAIL":add(level="WARNING", queue-length="10000", overflow-action="DISCARD", subhandlers=[MAIL])
Overflow action can be BLOCK if the version of WildFly has the fix for WFCORE-6596: AsyncHandler must not park worker thread. By default the AsyncHandler will auto-flush which can bypass the push filter cool down duration which will result in more smaller emails.
- Attach the MailHandler to the root logger. In the jbosscli (edit the module name if needed):
/subsystem=logging/root-logger=ROOT:add-handler(name="ASYNC_MAIL")
Additional features or bugs can be filed in the angus-mail issue tracker.
The other option is MailHandler supports getting and setting the mail properties. You can extend the MailHandler and add the needed property methods for WildFly.
public class WildFlyMailHandler extends MailHandler {
public WildFlyMailHandler() {
}
public void setHost(String host) {
setMailValue("mail.host", host);
}
public void setTo(String to) {
setMailValue("mail.to", to);
}
private void setMailValue(String key, String value) {
Properties p = getMailProperties();
p.setProperty(key, value);
setMailProperties(p);
}
}
You then install that jar as a module in WildFly.