You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2026/10/13 11:36:17 UTC
(james-project) 01/01: [ENHANCEMENT] AuditTrail should record which mapping were used upon rrt decision
This is an automated email from the ASF dual-hosted git repository.
chibenwa pushed a commit to branch rrt-log-mappings
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 255d03b735d13612d99f6995fb72d5b91d7fe26e
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Tue Oct 13 13:35:44 2026 +0200
[ENHANCEMENT] AuditTrail should record which mapping were used upon rrt decision
---
.../mailets/RecipientRewriteTableProcessor.java | 45 ++++++++++++++++++----
1 file changed, 37 insertions(+), 8 deletions(-)
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
index 1d04029c5d..94a7e82c64 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
@@ -81,16 +81,26 @@ public class RecipientRewriteTableProcessor {
private static class Decision {
private final MailAddress originalAddress;
private final RrtExecutionResult executionResult;
+ private final Optional<Mappings> appliedMappings;
- private Decision(MailAddress originalAddress, RrtExecutionResult executionResult) {
+ private Decision(MailAddress originalAddress, RrtExecutionResult executionResult, Optional<Mappings> appliedMappings) {
this.originalAddress = originalAddress;
this.executionResult = executionResult;
+ this.appliedMappings = appliedMappings;
+ }
+
+ private Decision(MailAddress originalAddress, RrtExecutionResult executionResult) {
+ this(originalAddress, executionResult, Optional.empty());
}
MailAddress originalAddress() {
return originalAddress;
}
+ Optional<String> describeAppliedMappings() {
+ return appliedMappings.map(mappings -> originalAddress.asString() + "=" + asString(mappings));
+ }
+
RrtExecutionResult executionResult() {
return executionResult;
}
@@ -220,7 +230,8 @@ public class RecipientRewriteTableProcessor {
.orElse(""),
"sender", mail.getMaybeSender().asString(),
"recipientsBeforeRewrite", StringUtils.join(recipientsBeforeRecipientsRewrite),
- "recipientsAfterRewrite", StringUtils.join(recipientsAfterRecipientsRewrite))))
+ "recipientsAfterRewrite", StringUtils.join(recipientsAfterRecipientsRewrite),
+ "appliedMappings", describeAppliedMappings(decisions))))
.log("Recipients rewritten.");
processForwards(mail);
@@ -236,7 +247,8 @@ public class RecipientRewriteTableProcessor {
static ForwardDecision sendACopy(MailetContext context,
MailAddress originalRecipient,
- Set<MailAddress> newRecipients) {
+ Set<MailAddress> newRecipients,
+ Set<Mapping> forwards) {
return mail -> {
MailImpl copy = MailImpl.duplicate(mail);
LoopPrevention.RecordedRecipients recordedRecipients = LoopPrevention.RecordedRecipients.fromMail(mail);
@@ -248,7 +260,7 @@ public class RecipientRewriteTableProcessor {
context.sendMail(copy);
- recordInAuditTrail(mail, copy, originalRecipient);
+ recordInAuditTrail(mail, copy, originalRecipient, forwards);
} finally {
LifecycleUtil.dispose(copy);
}
@@ -271,7 +283,7 @@ public class RecipientRewriteTableProcessor {
};
}
- private static void recordInAuditTrail(Mail mail, MailImpl copy, MailAddress originalRecipient) {
+ private static void recordInAuditTrail(Mail mail, MailImpl copy, MailAddress originalRecipient, Set<Mapping> forwards) {
AuditTrail.entry()
.protocol("mailetcontainer")
.action("RecipientRewrite")
@@ -282,7 +294,8 @@ public class RecipientRewriteTableProcessor {
"sender", mail.getMaybeSender().asString(),
"forwardedMailId", copy.getName(),
"forwardedMailSender", originalRecipient.asString(),
- "forwardedMailRecipient", StringUtils.join(copy.getRecipients()))))
+ "forwardedMailRecipient", StringUtils.join(copy.getRecipients()),
+ "forwardMappings", asString(forwards.stream()))))
.log("Mail forwarded.");
}
@@ -334,7 +347,7 @@ public class RecipientRewriteTableProcessor {
ImmutableList.Builder<ForwardDecision> result = ImmutableList.builder();
if (!forwardRecipients.isEmpty()) {
- result.add(ForwardDecision.sendACopy(mailetContext, originalRecipient, forwardRecipients));
+ result.add(ForwardDecision.sendACopy(mailetContext, originalRecipient, forwardRecipients, forwards));
}
boolean localCopy = newRecipients.contains(originalRecipient);
if (!localCopy) {
@@ -366,6 +379,22 @@ public class RecipientRewriteTableProcessor {
}
}
+ private static String describeAppliedMappings(List<Decision> decisions) {
+ return decisions.stream()
+ .map(Decision::describeAppliedMappings)
+ .flatMap(Optional::stream)
+ .collect(Collectors.joining(", ", "[", "]"));
+ }
+
+ private static String asString(Mappings mappings) {
+ return asString(mappings.asStream());
+ }
+
+ private static String asString(Stream<Mapping> mappings) {
+ return mappings.map(Mapping::asString)
+ .collect(Collectors.joining(", ", "[", "]"));
+ }
+
private void applyDecisionOnDSNParameters(Mail mail, List<Decision> decisions) {
mail.dsnParameters()
.map(dsnParameters -> decisions.stream()
@@ -418,7 +447,7 @@ public class RecipientRewriteTableProcessor {
if (mappings != null && !mappings.isEmpty()) {
List<MailAddress> newMailAddresses = handleMappings(mappings, mail, recipient);
- return new Decision(recipient, RrtExecutionResult.success(newMailAddresses));
+ return new Decision(recipient, RrtExecutionResult.success(newMailAddresses), Optional.of(mappings));
}
return new Decision(recipient, RrtExecutionResult.success(recipient));
} catch (RecipientRewriteTable.ErrorMappingException e) {
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org