This is an automated email from the ASF dual-hosted git repository.
jhelou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new a06577193f [JAMES-4128] improves Mailet config encapsulation
a06577193f is described below
commit a06577193f2f729c040c9449040d4c9a90b824a6
Author: Matthieu Baechler <[email protected]>
AuthorDate: Tue Mar 25 16:59:01 2025 +0100
[JAMES-4128] improves Mailet config encapsulation
The mailet configuration is injected from the mailet container, exposing it
back publicly breaks encapsulation.
We propose to remove the `getMailetConfig` method ( yes this is a breaking
api change ) and add 1 method to the interface to clarify the contract:
`String getName()` returns the name of the mailet. a default implementation
is `GenericMailet#getMailetName()` though we want to avoid repeating `Mailet`
in the interface.
---
CHANGELOG.md | 7 +-
.../src/main/java/org/apache/mailet/Mailet.java | 21 ++----
.../java/org/apache/mailet/base/GenericMailet.java | 5 +-
.../mailet/constructor/ConstructorMailet.java | 5 --
.../excluded/ExcludedFromDocumentationMailet.java | 5 --
.../NotExcludedFromDocumentationMailet.java | 5 --
.../mailet/experimental/ExperimentalMailet.java | 5 --
.../mailet/experimental/NonExperimentalMailet.java | 5 --
.../modules/server/MailetContainerModule.java | 65 ++++++++++--------
.../mailets/sub/ConstructorBoundTestMailet.java | 4 +-
.../apache/james/utils/GuiceMailetLoaderTest.java | 2 +-
.../api/mock/ExceptionThrowingMailet.java | 4 +-
.../james/mailetcontainer/api/mock/MockMailet.java | 4 +-
.../mailetcontainer/impl/MailetProcessorImpl.java | 2 +-
.../mailetcontainer/impl/MatcherMailetPair.java | 31 ++++++---
.../mailetcontainer/impl/MatcherSplitter.java | 3 +-
.../james/mailetcontainer/impl/ProcessorImpl.java | 29 ++++----
.../impl/jmx/JMXStateMailetProcessorListener.java | 14 +++-
.../mailetcontainer/impl/jmx/MailetManagement.java | 29 ++++----
.../lib/AbstractStateCompositeProcessor.java | 21 +++---
.../lib/AbstractStateMailetProcessor.java | 11 ++-
.../MailProcessingErrorHandlingConfiguration.java} | 79 ++++++++++------------
.../impl/MailetProcessorImplTest.java | 27 ++++----
.../lib/AbstractStateMailetProcessorTest.java | 77 ++++++++++++---------
.../james/samples/mailets/HelloWorldMailet.java | 8 +--
.../samples/mailets/InstrumentationMailet.java | 8 +--
upgrade-instructions.md | 13 ++++
27 files changed, 259 insertions(+), 230 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfd2fbdd80..841006b8ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,7 +10,9 @@ The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/)
- Upgrade javax -> jakarta. See releated upgrade instructions.
- Upgrade Java 11 -> 21. See related upgrade instructions.
- API change: CassandraModule and all associated Cassandra*Module were
renamed to CassandraDataDefinition and Cassandra*DataDefinition respectively.
-
+ - API change : Mailet API has been cleaned up and no longer exposes the
mailet config, exposing only the mailet's name instead.
+ - API change : GenericMailet can have its config bound by constructor and
this is the preferred way to initialize your mailets. `init` is still called
but will eventually be removed in a later release.
+
### Removals
- JAMES-3946 WhiteList manager removals (#2299)
@@ -82,7 +84,8 @@ Please use RFC-8621 implementation rather than this outdated
draft.
- JAMES-3824 SMTP Extension for Message Transfer Priorities
### Improvements
-
+
+ - JAMES-4125 rework mailet api
- JAMES-4123 Renames CassandraModule to CassandraDataDefinition
- JAMES-4103 Allow customizing MessageParser
- JAMES-3967 RelayLimit: add error log
diff --git a/mailet/api/src/main/java/org/apache/mailet/Mailet.java
b/mailet/api/src/main/java/org/apache/mailet/Mailet.java
index f59fc8b9dd..b9743da23c 100644
--- a/mailet/api/src/main/java/org/apache/mailet/Mailet.java
+++ b/mailet/api/src/main/java/org/apache/mailet/Mailet.java
@@ -42,10 +42,7 @@ import com.google.common.collect.ImmutableList;
* </ol>
* <p>
* In addition to the life-cycle methods, this interface provides the
- * {@link #getMailetConfig} method, which provides the Mailet with
- * its initialization parameters and a {@link MailetContext} through which
- * it can interact with the mailet container, and the {@link #getMailetInfo}
- * method, which provides basic information about the Mailet.
+ * {@link #getMailetInfo} method, which provides basic information about the
Mailet.
* <p>
* Mailets are grouped by the mailet container's configuration into processors.
* Each processor is comprised of an ordered sequence of Mailets, each with a
@@ -114,18 +111,12 @@ public interface Mailet {
}
/**
- * Returns a MailetConfig object, which provides initialization parameters
- * and a {@link MailetContext} through which it can interact with the
- * mailet container.
- * <p>
- * Implementations of this interface are responsible for storing the
- * MailetConfig which they receive in the {@link #init} method so
- * that this method can return it.
- *
- * @return the MailetConfig that this mailet was initialized with
+ * @return mailet name
*/
- MailetConfig getMailetConfig();
-
+ default String getName() {
+ return this.getClass().getSimpleName();
+ }
+
/**
* Returns information about the mailet, such as author, version and
* copyright.
diff --git
a/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
b/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
index 3f12f4bf22..cac316e745 100644
--- a/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
+++ b/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
@@ -177,7 +177,6 @@ public abstract class GenericMailet implements Mailet,
MailetConfig {
*
* @return the MailetConfig object that initialized this mailet
*/
- @Override
public MailetConfig getMailetConfig() {
return config;
}
@@ -204,6 +203,10 @@ public abstract class GenericMailet implements Mailet,
MailetConfig {
return config.getMailetName();
}
+ @Override
+ public String getName() {
+ return getMailetName();
+ }
/**
* <p>Called by the mailet container to indicate to a mailet that the
diff --git
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
index 905ef7b08b..9f6fcc76f1 100644
---
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
+++
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/constructor/ConstructorMailet.java
@@ -44,11 +44,6 @@ public class ConstructorMailet implements Mailet {
public void destroy() {
}
- @Override
- public MailetConfig getMailetConfig() {
- return null;
- }
-
@Override
public String getMailetInfo() {
return "info";
diff --git
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
index bc69216455..a728ab0e49 100644
---
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
+++
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/ExcludedFromDocumentationMailet.java
@@ -41,11 +41,6 @@ public class ExcludedFromDocumentationMailet implements
Mailet {
public void destroy() {
}
- @Override
- public MailetConfig getMailetConfig() {
- return null;
- }
-
@Override
public String getMailetInfo() {
return null;
diff --git
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
index 46405f0daa..7195d76b35 100644
---
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
+++
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/excluded/NotExcludedFromDocumentationMailet.java
@@ -39,11 +39,6 @@ public class NotExcludedFromDocumentationMailet implements
Mailet {
public void destroy() {
}
- @Override
- public MailetConfig getMailetConfig() {
- return null;
- }
-
@Override
public String getMailetInfo() {
return null;
diff --git
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
index 09fe15d9e1..dba296dd63 100644
---
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
+++
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/ExperimentalMailet.java
@@ -41,11 +41,6 @@ public class ExperimentalMailet implements Mailet {
public void destroy() {
}
- @Override
- public MailetConfig getMailetConfig() {
- return null;
- }
-
@Override
public String getMailetInfo() {
return null;
diff --git
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
index 107cfcc57a..db9fc08c74 100644
---
a/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
+++
b/mailet/mailetdocs-maven-plugin/src/test/java/org/apache/james/mailet/experimental/NonExperimentalMailet.java
@@ -39,11 +39,6 @@ public class NonExperimentalMailet implements Mailet {
public void destroy() {
}
- @Override
- public MailetConfig getMailetConfig() {
- return null;
- }
-
@Override
public String getMailetInfo() {
return null;
diff --git
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
index e6ef0a8e9b..9a7120f49b 100644
---
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
+++
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/MailetContainerModule.java
@@ -60,6 +60,7 @@ import org.apache.mailet.Mailet;
import org.apache.mailet.MailetContext;
import org.apache.mailet.Matcher;
import org.apache.mailet.base.AutomaticallySentMailDetector;
+import org.apache.mailet.base.GenericMailet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -83,11 +84,19 @@ public class MailetContainerModule extends AbstractModule {
private static final boolean MAILET_CONTAINER_CHECK_ENABLED =
Boolean.parseBoolean(System.getProperty("james.mailet.container.check.enabled",
"true"));
public static final ProcessorsCheck.Impl BCC_Check = new
ProcessorsCheck.Impl(
- "transport",
- All.class,
- RemoveMimeHeader.class,
- pair ->
Arrays.asList(pair.getMailet().getMailetConfig().getInitParameter("name").toLowerCase().split(",")).contains("bcc"),
- "Should be configured to remove Bcc header");
+ "transport",
+ All.class,
+ RemoveMimeHeader.class,
+ pair -> {
+ if (pair.getMailet() instanceof GenericMailet genericMailet) {
+ return Arrays
+
.asList(genericMailet.getMailetConfig().getInitParameter("name").toLowerCase().split(","))
+ .contains("bcc");
+ } else {
+ return false;
+ }
+ },
+ "Should be configured to remove Bcc header");
@Override
protected void configure() {
@@ -128,7 +137,7 @@ public class MailetContainerModule extends AbstractModule {
private HierarchicalConfiguration<ImmutableNode>
getJamesSpoolerConfiguration(ConfigurationProvider configurationProvider) {
try {
return configurationProvider.getConfiguration("mailetcontainer")
- .configurationAt("spooler");
+ .configurationAt("spooler");
} catch (Exception e) {
LOGGER.warn("Could not locate configuration for James Spooler.
Assuming empty configuration for this component.");
return new BaseHierarchicalConfiguration();
@@ -138,8 +147,8 @@ public class MailetContainerModule extends AbstractModule {
@ProvidesIntoSet
InitializationOperation initMailetContext(ConfigurationProvider
configurationProvider, JamesMailetContext mailetContext) {
return InitilizationOperationBuilder
- .forClass(JamesMailetContext.class)
- .init(() ->
mailetContext.configure(getMailetContextConfiguration(configurationProvider)));
+ .forClass(JamesMailetContext.class)
+ .init(() ->
mailetContext.configure(getMailetContextConfiguration(configurationProvider)));
}
@VisibleForTesting
@@ -206,19 +215,19 @@ public class MailetContainerModule extends AbstractModule
{
private void checkProcessors() throws ConfigurationException {
ImmutableListMultimap<String, MatcherMailetPair> processors =
Arrays.stream(compositeProcessorImpl.getProcessorStates())
- .flatMap(state -> {
- MailProcessor processor =
compositeProcessorImpl.getProcessor(state);
- if (processor instanceof MailetProcessorImpl) {
- MailetProcessorImpl camelProcessor =
(MailetProcessorImpl) processor;
- return camelProcessor.getPairs().stream()
- .map(pair -> Pair.of(state, pair));
- } else {
- throw new RuntimeException("Can not perform checks as
transport processor is not an instance of " + MailProcessor.class);
- }
- })
- .collect(ImmutableListMultimap.toImmutableListMultimap(
- Pair::getKey,
- Pair::getValue));
+ .flatMap(state -> {
+ MailProcessor processor =
compositeProcessorImpl.getProcessor(state);
+ if (processor instanceof MailetProcessorImpl) {
+ MailetProcessorImpl camelProcessor =
(MailetProcessorImpl) processor;
+ return camelProcessor.getPairs().stream()
+ .map(pair -> Pair.of(state, pair));
+ } else {
+ throw new RuntimeException("Can not perform checks
as transport processor is not an instance of " + MailProcessor.class);
+ }
+ })
+ .collect(ImmutableListMultimap.toImmutableListMultimap(
+ Pair::getKey,
+ Pair::getValue));
for (ProcessorsCheck check : processorsCheckSet) {
check.check(processors);
}
@@ -283,7 +292,7 @@ public class MailetContainerModule extends AbstractModule {
this(processorName, matcherClass, mailetClass,
Optional.empty(), Optional.empty());
}
- public Impl(String processorName, Class<? extends Matcher>
matcherClass, Class<? extends Mailet> mailetClass, Predicate<? super
MatcherMailetPair> additionalFilter, String additionalErrorMessage) {
+ public Impl(String processorName, Class<? extends Matcher>
matcherClass, Class<? extends GenericMailet> mailetClass, Predicate<? super
MatcherMailetPair> additionalFilter, String additionalErrorMessage) {
this(processorName, matcherClass, mailetClass,
Optional.of(additionalFilter), Optional.of(additionalErrorMessage));
}
@@ -303,12 +312,12 @@ public class MailetContainerModule extends AbstractModule
{
}
Preconditions.checkNotNull(pairs);
pairs.stream()
- .filter(pair ->
pair.getMailet().getClass().equals(mailetClass))
- .filter(pair ->
pair.getMatcher().getClass().equals(matcherClass))
- .filter(additionalFilter.orElse(any -> true))
- .findAny()
- .orElseThrow(() -> new ConfigurationException("Missing " +
mailetClass.getName() + " in mailets configuration (mailetcontainer ->
processors -> " + processorName + "). " +
- additionalErrorMessage.orElse("")));
+ .filter(pair ->
pair.getMailet().getClass().equals(mailetClass))
+ .filter(pair ->
pair.getMatcher().getClass().equals(matcherClass))
+ .filter(additionalFilter.orElse(any -> true))
+ .findAny()
+ .orElseThrow(() -> new ConfigurationException("Missing
" + mailetClass.getName() + " in mailets configuration (mailetcontainer ->
processors -> " + processorName + "). " +
+ additionalErrorMessage.orElse("")));
}
}
}
diff --git
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
b/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
index ed582c04c1..a05fae1f69 100644
---
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
+++
b/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
@@ -40,7 +40,7 @@ public class ConstructorBoundTestMailet implements Mailet {
}
@Override
- public MailetConfig getMailetConfig() {
- return config;
+ public String getName() {
+ return config.getMailetName();
}
}
diff --git
a/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
b/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
index 792955cd0a..b8591e2a33 100644
---
a/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
+++
b/server/container/guice/mailet/src/test/java/org/apache/james/utils/GuiceMailetLoaderTest.java
@@ -68,7 +68,7 @@ class GuiceMailetLoaderTest {
.build());
assertThat(mailet).isInstanceOf(ConstructorBoundTestMailet.class);
- assertThat(mailet.getMailetConfig()).isNotNull();
+
assertThat(mailet.getName()).isEqualTo("sub.ConstructorBoundTestMailet");
}
@Test
diff --git
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
index 61b98ce44d..2763c042e6 100644
---
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
+++
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/ExceptionThrowingMailet.java
@@ -33,8 +33,8 @@ public class ExceptionThrowingMailet implements Mailet {
}
@Override
- public MailetConfig getMailetConfig() {
- return config;
+ public String getName() {
+ return config.getMailetName();
}
@Override
diff --git
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
index 1e128f34ea..c673577831 100644
---
a/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
+++
b/server/mailet/mailetcontainer-api/src/test/java/org/apache/james/mailetcontainer/api/mock/MockMailet.java
@@ -31,8 +31,8 @@ public class MockMailet implements Mailet {
}
@Override
- public MailetConfig getMailetConfig() {
- return config;
+ public String getName() {
+ return config.getMailetName();
}
@Override
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
index e1440a52ab..a76e164c43 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MailetProcessorImpl.java
@@ -202,7 +202,7 @@ public class MailetProcessorImpl extends
AbstractStateMailetProcessor {
this.pairs = pairs;
this.pairsToBeProcessed = pairs.stream()
.map(pair -> Pair.of(new MatcherSplitter(metricFactory, this,
pair),
- new ProcessorImpl(metricFactory, this, pair.getMailet())))
+ new ProcessorImpl(metricFactory, pair.getMailet(),
pair.processingErrorConfig(), this.getListeners())))
.collect(ImmutableMap.toImmutableMap(Pair::getKey,
Pair::getValue));
} catch (Exception e) {
throw new MessagingException("Unable to setup routing for
MailetMatcherPairs", e);
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
index b2d1540239..1d8585ab31 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherMailetPair.java
@@ -18,24 +18,30 @@
****************************************************************/
package org.apache.james.mailetcontainer.impl;
+import java.util.Optional;
+
+import
org.apache.james.mailetcontainer.lib.MailProcessingErrorHandlingConfiguration;
import org.apache.mailet.Mailet;
import org.apache.mailet.Matcher;
+import com.google.common.annotations.VisibleForTesting;
+
/**
* A pair of {@link Matcher} and {@link Mailet}
*/
-public class MatcherMailetPair {
- private final Matcher matcher;
- private final Mailet mailet;
-
+public record MatcherMailetPair(
+ Matcher matcher,
+ Mailet mailet,
+ MailProcessingErrorHandlingConfiguration processingErrorConfig
+) {
+ @VisibleForTesting
public MatcherMailetPair(Matcher matcher, Mailet mailet) {
- this.matcher = matcher;
- this.mailet = mailet;
+ this(matcher, mailet,
MailProcessingErrorHandlingConfiguration.empty());
}
/**
* Return the {@link Matcher} of this pair
- *
+ *
* @return matcher
*/
public Matcher getMatcher() {
@@ -44,16 +50,19 @@ public class MatcherMailetPair {
/**
* Return the {@link Mailet} of this pair
- *
+ *
* @return mailet
*/
public Mailet getMailet() {
return mailet;
}
- public String getOnMatchException() {
- return mailet.getMailetConfig()
- .getInitParameter("onMatchException");
+ public Optional<String> onMatchException() {
+ return processingErrorConfig.onMatchException();
+ }
+
+ public Optional<String> onMailetException() {
+ return processingErrorConfig.onMailetException();
}
}
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
index 84d3564a97..9e872bd675 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
-import java.util.Optional;
import jakarta.mail.MessagingException;
@@ -63,7 +62,7 @@ public class MatcherSplitter {
this.metricFactory = metricFactory;
this.container = container;
this.matcher = pair.getMatcher();
- this.onMatchException = Optional.ofNullable(pair.getOnMatchException())
+ this.onMatchException = pair.onMatchException()
.map(s -> s.trim().toLowerCase(Locale.US))
.orElse(Mail.ERROR);
}
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
index 2fe5c0e80d..416f284e5a 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Locale;
import
org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor.MailetProcessorListener;
+import
org.apache.james.mailetcontainer.lib.MailProcessingErrorHandlingConfiguration;
import org.apache.james.metrics.api.MetricFactory;
import org.apache.james.metrics.api.TimeMetric;
import org.apache.james.util.MDCBuilder;
@@ -30,7 +31,6 @@ import org.apache.mailet.Attribute;
import org.apache.mailet.AttributeValue;
import org.apache.mailet.Mail;
import org.apache.mailet.Mailet;
-import org.apache.mailet.MailetConfig;
import org.apache.mailet.base.MailetPipelineLogging;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,12 +44,19 @@ public class ProcessorImpl {
private static final Logger LOGGER =
LoggerFactory.getLogger(ProcessorImpl.class);
private final MetricFactory metricFactory;
+ private final MailProcessingErrorHandlingConfiguration
processingErrorHandlingConfiguration;
+ private final List<MailetProcessorListener> listeners;
private final Mailet mailet;
- private final MailetProcessorImpl processor;
- public ProcessorImpl(MetricFactory metricFactory, MailetProcessorImpl
processor, Mailet mailet) {
+ public ProcessorImpl(
+ MetricFactory metricFactory,
+ Mailet mailet,
+ MailProcessingErrorHandlingConfiguration
processingErrorHandlingConfiguration,
+ List<MailetProcessorListener> listeners
+ ) {
this.metricFactory = metricFactory;
- this.processor = processor;
+ this.processingErrorHandlingConfiguration =
processingErrorHandlingConfiguration;
+ this.listeners = listeners;
this.mailet = mailet;
}
@@ -81,17 +88,8 @@ public class ProcessorImpl {
mailet.service(mail);
} catch (Throwable me) {
ex = me;
- String onMailetException = null;
+ String onMailetException =
processingErrorHandlingConfiguration.onMailetException().map(value ->
value.trim().toLowerCase(Locale.US)).orElse(Mail.ERROR);
- MailetConfig mailetConfig = mailet.getMailetConfig();
- if (mailetConfig instanceof MailetConfigImpl) {
- onMailetException =
mailetConfig.getInitParameter("onMailetException");
- }
- if (onMailetException == null) {
- onMailetException = Mail.ERROR;
- } else {
- onMailetException =
onMailetException.trim().toLowerCase(Locale.US);
- }
if (onMailetException.equalsIgnoreCase("ignore")) {
// ignore the exception and continue
// this option should not be used if the mail object can be
@@ -101,13 +99,12 @@ public class ProcessorImpl {
} else if (onMailetException.equalsIgnoreCase("propagate")) {
throw me;
} else {
- ProcessorUtil.handleException(me, mail,
mailet.getMailetConfig().getMailetName(), onMailetException, LOGGER);
+ ProcessorUtil.handleException(me, mail, mailet.getName(),
onMailetException, LOGGER);
}
} finally {
timeMetric.stopAndPublish();
MailetPipelineLogging.logEndOfMailetProcess(mailet, mail);
- List<MailetProcessorListener> listeners = processor.getListeners();
long complete = System.currentTimeMillis() - start;
if (mail.getRecipients().isEmpty()) {
mail.setState(Mail.GHOST);
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
index bc4bdbc09f..028ea14451 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/JMXStateMailetProcessorListener.java
@@ -25,9 +25,11 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import javax.management.JMException;
import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import org.apache.james.core.MailAddress;
@@ -36,7 +38,9 @@ import
org.apache.james.mailetcontainer.impl.matchers.CompositeMatcher;
import org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor;
import
org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor.MailetProcessorListener;
import org.apache.mailet.Mailet;
+import org.apache.mailet.MailetConfig;
import org.apache.mailet.Matcher;
+import org.apache.mailet.base.GenericMailet;
/**
* {@link MailetProcessorListener} implementation which register MBean's for
all
@@ -98,7 +102,7 @@ public class JMXStateMailetProcessorListener implements
MailetProcessorListener,
int i = 0;
while (mailets.hasNext()) {
Mailet mailet = mailets.next();
- MailetManagement mailetManagement = new
MailetManagement(mailet.getMailetConfig());
+ MailetManagement mailetManagement = new
MailetManagement(getOptionalMailetConfig(mailet), mailet.getName());
String mailetMBeanName = parentMBeanName +
",subtype=mailet,index=" + (i++) + ",mailetname=" +
mailetManagement.getMailetName();
registerMBean(mailetMBeanName, mailetManagement);
@@ -107,6 +111,14 @@ public class JMXStateMailetProcessorListener implements
MailetProcessorListener,
}
+ private Optional<MailetConfig> getOptionalMailetConfig(Mailet mailet)
throws NotCompliantMBeanException {
+ if (mailet instanceof GenericMailet m) {
+ return Optional.ofNullable(m.getMailetConfig());
+ } else {
+ return Optional.empty();
+ }
+ }
+
/**
* Register the {@link Matcher}'s as JMX MBeans
*/
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
index 5ae817124d..9b48e4b08d 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/jmx/MailetManagement.java
@@ -21,6 +21,7 @@ package org.apache.james.mailetcontainer.impl.jmx;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.atomic.AtomicLong;
import javax.management.NotCompliantMBeanException;
@@ -37,12 +38,13 @@ public final class MailetManagement extends StandardMBean
implements MailetManag
private final AtomicLong slowestProcessing = new AtomicLong(-1);
private final AtomicLong lastProcessing = new AtomicLong(-1);
- private final MailetConfig config;
+ private final Optional<MailetConfig> config;
+ private final String mailetName;
- public MailetManagement(MailetConfig config) throws
NotCompliantMBeanException {
+ public MailetManagement(Optional<MailetConfig> config, String mailetName)
throws NotCompliantMBeanException {
super(MailetManagementMBean.class);
this.config = config;
-
+ this.mailetName = mailetName;
}
public void update(long processTime, boolean success) {
@@ -65,19 +67,22 @@ public final class MailetManagement extends StandardMBean
implements MailetManag
@Override
public String getMailetName() {
- return config.getMailetName();
+ return mailetName;
}
@Override
public String[] getMailetParameters() {
- List<String> parameterList = new ArrayList<>();
- Iterator<String> iterator = config.getInitParameterNames();
- while (iterator.hasNext()) {
- String name = iterator.next();
- String value = config.getInitParameter(name);
- parameterList.add(name + "=" + value);
- }
- return parameterList.toArray(String[]::new);
+ return config.map(c -> {
+ List<String> parameterList = new ArrayList<>();
+ Iterator<String> iterator = c.getInitParameterNames();
+ while (iterator.hasNext()) {
+ String name = iterator.next();
+ String value = c.getInitParameter(name);
+ parameterList.add(name + "=" + value);
+ }
+ return parameterList.toArray(String[]::new);
+ }
+ ).orElse(new String[0]);
}
@Override
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
index 77446cee39..a176a7b5d9 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateCompositeProcessor.java
@@ -42,7 +42,6 @@ import
org.apache.james.mailetcontainer.impl.MatcherMailetPair;
import org.apache.james.mailetcontainer.impl.ProcessorImpl;
import
org.apache.james.mailetcontainer.impl.jmx.JMXStateCompositeProcessorListener;
import org.apache.mailet.Mail;
-import org.apache.mailet.Mailet;
import org.apache.mailet.ProcessingState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -137,7 +136,7 @@ public abstract class AbstractStateCompositeProcessor
implements MailProcessor,
.stream()
.filter(MailetProcessorImpl.class::isInstance)
.map(MailetProcessorImpl.class::cast)
- .flatMap(processor ->
processor.getPairs().stream().map(MatcherMailetPair::getMailet))
+ .flatMap(processor -> processor.getPairs().stream())
.flatMap(this::requiredProcessorStates)
.filter(state -> !state.equals(new ProcessingState("propagate"))
&& !state.equals(new ProcessingState("ignore"))
@@ -151,13 +150,17 @@ public abstract class AbstractStateCompositeProcessor
implements MailProcessor,
}
}
- private Stream<ProcessingState> requiredProcessorStates(Mailet mailet) {
- return Stream.concat(mailet.requiredProcessingState().stream(),
- Stream.of(
-
Optional.ofNullable(mailet.getMailetConfig().getInitParameter("onMailetException")),
-
Optional.ofNullable(mailet.getMailetConfig().getInitParameter("onMatchException")))
- .flatMap(Optional::stream)
- .map(ProcessingState::new));
+ private Stream<ProcessingState> requiredProcessorStates(MatcherMailetPair
matcherMailetPair) {
+ var mailet = matcherMailetPair.getMailet();
+
+ return Stream.concat(
+ mailet.requiredProcessingState().stream(),
+ Stream.of(
+ matcherMailetPair.onMailetException(),
+ matcherMailetPair.onMatchException()
+ ).flatMap(Optional::stream)
+ .map(ProcessingState::new)
+ );
}
@PostConstruct
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
index c031b5e4ea..eb5b6b6c36 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessor.java
@@ -319,7 +319,8 @@ public abstract class AbstractStateMailetProcessor
implements MailProcessor, Con
throw new ConfigurationException("Unable to init matcher " +
matcherName, ex);
}
try {
- mailet =
mailetLoader.getMailet(createMailetConfig(mailetClassName, c));
+ MailetConfig mailetConfig =
createMailetConfig(mailetClassName, c);
+ mailet = mailetLoader.getMailet(mailetConfig);
LOGGER.info("Mailet {} instantiated.", mailetClassName);
} catch (MessagingException ex) {
// **** Do better job printing out exception
@@ -331,7 +332,13 @@ public abstract class AbstractStateMailetProcessor
implements MailProcessor, Con
}
if (matcher != null && mailet != null) {
- pairs.add(new MatcherMailetPair(matcher, mailet));
+ var processingErrorConfig = new
MailProcessingErrorHandlingConfiguration(
+ Optional.ofNullable(c.getString("onMailetException")),
+ Optional.ofNullable(c.getString("onMatchException"))
+ );
+
+
+ pairs.add(new MatcherMailetPair(matcher, mailet,
processingErrorConfig));
} else {
throw new ConfigurationException("Unable to load Mailet or
Matcher");
}
diff --git
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/MailProcessingErrorHandlingConfiguration.java
similarity index 61%
copy from
server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
copy to
server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/MailProcessingErrorHandlingConfiguration.java
index ed582c04c1..75b7f1a139 100644
---
a/server/container/guice/mailet/src/test/java/org/apache/james/transport/mailets/sub/ConstructorBoundTestMailet.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/lib/MailProcessingErrorHandlingConfiguration.java
@@ -1,46 +1,35 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.transport.mailets.sub;
-
-import jakarta.inject.Inject;
-import jakarta.mail.MessagingException;
-
-import org.apache.mailet.Mail;
-import org.apache.mailet.Mailet;
-import org.apache.mailet.MailetConfig;
-
-public class ConstructorBoundTestMailet implements Mailet {
- private final MailetConfig config;
-
- @Inject
- public ConstructorBoundTestMailet(MailetConfig config) {
- this.config = config;
- }
-
- @Override
- public void service(Mail mail) throws MessagingException {
-
- }
-
- @Override
- public MailetConfig getMailetConfig() {
- return config;
+/******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+
******************************************************************************/
+
+package org.apache.james.mailetcontainer.lib;
+
+import java.util.Optional;
+
+public record MailProcessingErrorHandlingConfiguration(
+ Optional<String> onMailetException,
+ Optional<String> onMatchException
+) {
+ public static MailProcessingErrorHandlingConfiguration empty() {
+ return new MailProcessingErrorHandlingConfiguration(
+ Optional.empty(),
+ Optional.empty()
+
+ );
}
-}
+}
\ No newline at end of file
diff --git
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
index 51ba22afb0..65d18d6193 100644
---
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
+++
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/impl/MailetProcessorImplTest.java
@@ -21,6 +21,8 @@ package org.apache.james.mailetcontainer.impl;
import static org.mockito.Mockito.mock;
+import java.util.Collection;
+
import org.apache.commons.configuration2.HierarchicalConfiguration;
import org.apache.commons.configuration2.tree.ImmutableNode;
import org.apache.james.mailetcontainer.api.MailProcessor;
@@ -34,22 +36,19 @@ import org.apache.mailet.base.test.FakeMailContext;
public class MailetProcessorImplTest extends AbstractStateMailetProcessorTest {
@Override
- protected AbstractStateMailetProcessor
createProcessor(HierarchicalConfiguration<ImmutableNode> configuration) throws
Exception {
+ protected AbstractStateMailetProcessor
createProcessor(HierarchicalConfiguration<ImmutableNode> configuration,
Collection<AbstractStateMailetProcessor.MailetProcessorListener> listeners)
throws Exception {
MailetProcessorImpl processor = null;
- try {
- processor = new MailetProcessorImpl("anyName", new
RecordingMetricFactory());
- processor.setMailetContext(FakeMailContext.defaultContext());
- processor.setMailetLoader(new MockMailetLoader());
- processor.setMatcherLoader(new MockMatcherLoader());
- processor.setRootMailProcessor(mock(MailProcessor.class));
- processor.configure(configuration);
- processor.init();
- return processor;
- } finally {
- if (processor != null) {
- processor.destroy();
- }
+ processor = new MailetProcessorImpl("anyName", new
RecordingMetricFactory());
+ processor.setMailetContext(FakeMailContext.defaultContext());
+ processor.setMailetLoader(new MockMailetLoader());
+ processor.setMatcherLoader(new MockMatcherLoader());
+ processor.setRootMailProcessor(mock(MailProcessor.class));
+ processor.configure(configuration);
+ for (var listener : listeners) {
+ processor.addListener(listener);
}
+ processor.init();
+ return processor;
}
}
diff --git
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
index 8e467d287a..29a04381b9 100644
---
a/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
+++
b/server/mailet/mailetcontainer-impl/src/test/java/org/apache/james/mailetcontainer/lib/AbstractStateMailetProcessorTest.java
@@ -23,7 +23,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.io.ByteArrayInputStream;
import java.util.Collection;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import jakarta.mail.MessagingException;
@@ -47,8 +49,10 @@ import org.junit.jupiter.api.Test;
public abstract class AbstractStateMailetProcessorTest {
- protected abstract AbstractStateMailetProcessor
createProcessor(HierarchicalConfiguration<ImmutableNode> configuration) throws
- Exception;
+ protected abstract AbstractStateMailetProcessor createProcessor(
+ HierarchicalConfiguration<ImmutableNode> configuration,
+ Collection<AbstractStateMailetProcessor.MailetProcessorListener>
listeners
+ ) throws Exception;
private HierarchicalConfiguration<ImmutableNode> createConfig(Class<?>
matcherClass, Class<?> mailetClass, int count) throws
ConfigurationException {
@@ -69,9 +73,7 @@ public abstract class AbstractStateMailetProcessorTest {
final CountDownLatch latch = new CountDownLatch(2);
final MailImpl mail = newMail();
- AbstractStateMailetProcessor processor =
createProcessor(createConfig(MockMatcher.class, MockMailet.class, 1));
- processor.addListener(new MailetProcessorListener() {
-
+ MailetProcessorListener listener = new MailetProcessorListener() {
@Override
public void afterMatcher(Matcher m, String mailName,
Collection<MailAddress> recipients,
Collection<MailAddress> matches, long
processTime, Throwable e) {
@@ -96,7 +98,11 @@ public abstract class AbstractStateMailetProcessorTest {
latch.countDown();
}
}
- });
+ };
+ AbstractStateMailetProcessor processor = createProcessor(
+ createConfig(MockMatcher.class, MockMailet.class, 1),
+ List.of(listener)
+ );
assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
processor.service(mail);
@@ -104,7 +110,7 @@ public abstract class AbstractStateMailetProcessorTest {
// the source mail should be ghosted as it reached the end of
processor as only one recipient matched
assertThat(mail.getState()).isEqualTo(Mail.GHOST);
- latch.await();
+ assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
processor.destroy();
}
@@ -114,8 +120,7 @@ public abstract class AbstractStateMailetProcessorTest {
final CountDownLatch latch = new CountDownLatch(2);
final MailImpl mail = newMail();
- AbstractStateMailetProcessor processor =
createProcessor(createConfig(MockMatcher.class, MockMailet.class, 2));
- processor.addListener(new MailetProcessorListener() {
+ MailetProcessorListener listener = new MailetProcessorListener() {
@Override
public void afterMatcher(Matcher m, String mailName,
Collection<MailAddress> recipients,
@@ -142,7 +147,11 @@ public abstract class AbstractStateMailetProcessorTest {
latch.countDown();
}
}
- });
+ };
+ AbstractStateMailetProcessor processor = createProcessor(
+ createConfig(MockMatcher.class, MockMailet.class, 2),
+ List.of(listener)
+ );
assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
processor.service(mail);
@@ -150,7 +159,7 @@ public abstract class AbstractStateMailetProcessorTest {
// the source mail should have the new state as it was a full match
assertThat(mail.getState()).isEqualTo("test");
- latch.await();
+ assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
processor.destroy();
}
@@ -160,9 +169,7 @@ public abstract class AbstractStateMailetProcessorTest {
final CountDownLatch latch = new CountDownLatch(1);
final MailImpl mail = newMail();
- AbstractStateMailetProcessor processor =
createProcessor(createConfig(ExceptionThrowingMatcher.class,
- MockMailet.class, 0));
- processor.addListener(new MailetProcessorListener() {
+ MailetProcessorListener listener = new MailetProcessorListener() {
@Override
public void afterMatcher(Matcher m, String mailName,
Collection<MailAddress> recipients,
@@ -181,7 +188,11 @@ public abstract class AbstractStateMailetProcessorTest {
public void afterMailet(Mailet m, String mailName, String state,
long processTime, Throwable e) {
throw new RuntimeException("Should not call any mailet!");
}
- });
+ };
+ AbstractStateMailetProcessor processor = createProcessor(
+ createConfig(ExceptionThrowingMatcher.class, MockMailet.class,
0),
+ List.of(listener)
+ );
assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
@@ -189,7 +200,7 @@ public abstract class AbstractStateMailetProcessorTest {
// the source mail should have state error as the exception was thrown
assertThat(mail.getState()).isEqualTo(Mail.ERROR);
- latch.await();
+ assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
processor.destroy();
}
@@ -199,9 +210,7 @@ public abstract class AbstractStateMailetProcessorTest {
final CountDownLatch latch = new CountDownLatch(1);
final MailImpl mail = newMail();
- AbstractStateMailetProcessor processor =
createProcessor(createConfig(ExceptionThrowingMatcher.class,
- MockMailet.class, 0));
- processor.addListener(new MailetProcessorListener() {
+ MailetProcessorListener listener = new MailetProcessorListener() {
@Override
public void afterMatcher(Matcher m, String mailName,
Collection<MailAddress> recipients,
@@ -216,14 +225,18 @@ public abstract class AbstractStateMailetProcessorTest {
public void afterMailet(Mailet m, String mailName, String state,
long processTime, Throwable e) {
throw new RuntimeException("Should not call any mailet!");
}
- });
+ };
+ AbstractStateMailetProcessor processor = createProcessor(
+ createConfig(ExceptionThrowingMatcher.class, MockMailet.class,
0),
+ List.of(listener)
+ );
processor.service(mail);
// the source mail should have captured the exception which was thrown
assertThat(mail.getAttribute(Mail.MAILET_ERROR)).hasValueSatisfying(attribute ->
assertThat(attribute.getValue().value().getClass()).isEqualTo(MessagingException.class));
- latch.await();
+ assertThat(latch.await(3L, TimeUnit.SECONDS)).isTrue();
processor.destroy();
}
@@ -232,9 +245,7 @@ public abstract class AbstractStateMailetProcessorTest {
final CountDownLatch latch = new CountDownLatch(2);
final MailImpl mail = newMail();
- AbstractStateMailetProcessor processor =
createProcessor(createConfig(MockMatcher.class,
- ExceptionThrowingMailet.class, 1));
- processor.addListener(new MailetProcessorListener() {
+ MailetProcessorListener listener = new MailetProcessorListener() {
@Override
public void afterMatcher(Matcher m, String mailName,
Collection<MailAddress> recipients,
@@ -259,7 +270,11 @@ public abstract class AbstractStateMailetProcessorTest {
latch.countDown();
}
}
- });
+ };
+ AbstractStateMailetProcessor processor = createProcessor(
+ createConfig(MockMatcher.class, ExceptionThrowingMailet.class,
1),
+ List.of(listener)
+ );
assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
@@ -272,11 +287,11 @@ public abstract class AbstractStateMailetProcessorTest {
private MailImpl newMail() throws MessagingException {
return MailImpl.builder()
- .name(MailImpl.getId())
- .sender("test@localhost")
- .addRecipient("test@localhost")
- .addRecipient("test2@localhost")
- .mimeMessage(MimeMessageUtil.mimeMessageFromBytes("header:
value\r\n".getBytes(UTF_8)))
- .build();
+ .name(MailImpl.getId())
+ .sender("test@localhost")
+ .addRecipient("test@localhost")
+ .addRecipient("test2@localhost")
+ .mimeMessage(MimeMessageUtil.mimeMessageFromBytes("header:
value\r\n".getBytes(UTF_8)))
+ .build();
}
}
diff --git
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
index 186d08756b..8dcfd2744c 100644
---
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
+++
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/HelloWorldMailet.java
@@ -38,13 +38,13 @@ public class HelloWorldMailet implements Mailet {
}
@Override
- public String getMailetInfo() {
- return "Example mailet";
+ public String getName() {
+ return config.getMailetName();
}
@Override
- public MailetConfig getMailetConfig() {
- return config;
+ public String getMailetInfo() {
+ return "Example mailet";
}
@Override
diff --git
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
index 9523513d60..046696f917 100644
---
a/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
+++
b/server/mailet/mailets/src/test/java/org/apache/james/samples/mailets/InstrumentationMailet.java
@@ -53,13 +53,13 @@ public class InstrumentationMailet implements Mailet {
}
@Override
- public String getMailetInfo() {
- return "Example mailet";
+ public String getName() {
+ return config.getMailetName();
}
@Override
- public MailetConfig getMailetConfig() {
- return config;
+ public String getMailetInfo() {
+ return "Example mailet";
}
@Override
diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index 755ef83bad..c7a01d6f8f 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -36,6 +36,19 @@ Change list:
- [JAMES-4052 Details in quota index](#james-4052-details-in-quota-index)
- [JAMES-1409 Change JPARecipientRewriteTable to store separate record per
target
address](#james-1409-change-jparecipientrewritetable-to-store-separate-record-per-target-address)
- [JAMES-4118 Cleanup message previews](#james-4118-cleanup-message-previews)
+ - [JAMES-4128 Breaking Mailet API
changes](#james-4128-breaking-mailet-api-changes)
+
+### JAMES-4128 Breaking Mailet API changes
+Date: 02/04/2025
+
+JIRA: https://issues.apache.org/jira/browse/JAMES-4126
+
+The Mailet API has been slightly reworked to improve mailet encapsulation and
make implementation easier.
+
+- Method getMailetConfig() has been removed
+- Method getName() has been added with a default to the simple class name
+- implementers no longer have to override getMailetInfo, init or destroy
+- implementers of mailets can inject the configuration through the constructor
when using guice. Constructor injection of the config is not compatible with
spring applications.
### JAMES-4118 Cleanup message previews
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]