Distributed James Server — Extending server behavior
Available extension mechanisms
The Distributed Server exposes several interfaces allowing the user to write custom extensions in order to extend the Distributed Server behavior.
Writing Mailets and Matchers allows one to supply custom components for the Mail Processing and enables to take decisions, and implement your business logic at the transport level.
Writing Mailbox listeners enables to react to your user interaction with their mailbox. This powerful tool allows build advanced features for mail delivery servers.
Writing SMTP hookd enables to add features to your SMTP server.
Writing WebAdmin routes enables to add features to the WebAdmin REST API.
Handling injections for your extensions
Injecting core components
You can very easily inject core components into your custom extensions.
All you need is to pass them via a constructor annotated via @Inject.
For instance:
public class MyMailet extends GenericMailet { private final UsersRepository usersRepository; @Inject public MyMailet(UsersRepository usersRepository) { this.usersRepository = usersRepository; } @Override public void service(Mail mail) throws MessagingException { // Do something } }
Injecting simple extension components
Furthermore, concrete implementation, that are part of your extension, can be injected as well.
Consider the following example:
public class MyService { } public class MyMailet extends GenericMailet { private final MyService myService; @Inject public MyMailet(MyService myService) { this.usersRepository = myService; } @Override public void service(Mail mail) throws MessagingException { // Do something } }
Defining custom injections for your extensions
However, to inject an interface into your extension, you will need additional injection definitions.
To to so:
-
1. Given an interface defined in a additional JAR:
public interface MyService {}
-
2. And an implementation of that interface, in another additional JAR:
public class MyServiceImpl extends MyService {}
-
3. We need to define a binding for MyService to be bound to MyServiceImpl
public class MyServiceModule extends AbstractModule { @Override protected void configure() { bind(MyServiceImpl.class).in(Scopes.SINGLETON); bind(MyService.class).to(MyServiceImpl.class); } }
Both MyService, MyServiceImpl and MyServiceModule needs to be in the extensions-jars folder (potentially different jars).
-
4. MyServiceModule needs to be registered in extensions.properties
-
5. MyService can then be used as part of your extensions
public class MyMailet extends GenericMailet { private final MyService myService; @Inject public MyMailet(MyService myService) { this.usersRepository = myService; } @Override public void service(Mail mail) throws MessagingException { // Do something } }
Note that overriding injection definitions of the Distributed Server for your injections is not supported.
Pre-packaged extensions
Rate Limiting for mailet processing
Vendor: Apache Foundation (James project), Apache License V2
Project link contains detailed set up instructions and configuration examples as well as a pre-configured docker-compose.
This extension ships mailets for applying advanced rate limit criteria to the email transiting through your James server. It is shipped with two backends implemented:
-
in memory: For single server mode.
-
Redis: Uses Redis as a shared, fast and scalable in-memory datastore, allowing to apply rate limiting in a distributed fashion. Here is the link to the Redis extension for rate limiting.
-
Alternative extensions can be written and loaded into James using the Guice extension mechanism and providing custom injections for the
RateLimiterFactoryProvider
class.
This extension ships the following mailets:
-
PerSenderRateLimit
allows defining limits applied to the senders of emails (count of email, count of recipients, size, size * recipients) -
PerRecipientRateLimit
allows defining limits applied to the recipients of emails (count of email, size) -
GlobalRateLimit
allows defining limits applied to all the emails (count of email, count of recipients, size, size * recipients)
Depending on their positions and the matcher they are being combined with, those rate limiting rules could be applied to submitted emails, received emails or emitted email being relayed to third parties.
Throttling
Can use combine with Requeue
mailet for a throttler by re-enqueue mail.
link