JAMES-2220 rework MailImpl mailid generation to make it pass tests
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/31707935 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/31707935 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/31707935 Branch: refs/heads/master Commit: 31707935a2318792b609604cd9e6b40311be40ef Parents: c80bc05 Author: Matthieu Baechler <matth...@apache.org> Authored: Tue Nov 14 17:26:04 2017 +0100 Committer: Antoine Duprat <adup...@linagora.com> Committed: Thu Nov 16 12:30:31 2017 +0100 ---------------------------------------------------------------------- .../org/apache/james/server/core/MailImpl.java | 52 +++++++++++--------- .../apache/james/server/core/MailImplTest.java | 3 -- 2 files changed, 29 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/31707935/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java ---------------------------------------------------------------------- diff --git a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java index 4ba435c..c5c7f9b 100644 --- a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java +++ b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java @@ -39,6 +39,7 @@ import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import javax.mail.internet.ParseException; +import org.apache.commons.lang.RandomStringUtils; import org.apache.james.core.MailAddress; import org.apache.james.lifecycle.api.Disposable; import org.apache.james.lifecycle.api.LifecycleUtil; @@ -51,6 +52,7 @@ import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Chars; /** * <p> @@ -82,41 +84,45 @@ public class MailImpl implements Disposable, Mail { return new MailImpl(mail, deriveNewName(mail.getName())); } - private static final java.util.Random random = new java.util.Random(); // Used - // to - // generate - // new - // mail - // names - /** * Create a unique new primary key name for the given MailObject. + * Detect if this has been called more than 8 times recursively * * @param currentName the mail to use as the basis for the new mail name * @return a new name */ @VisibleForTesting static String deriveNewName(String currentName) throws MessagingException { + char separator = '!'; + int loopThreshold = 7; + int suffixLength = 9; + int suffixMaxLength = loopThreshold * suffixLength; + int nameMaxLength = suffixMaxLength + 13; + + detectPossibleLoop(currentName, loopThreshold, separator); // Checking if the original mail name is too long, perhaps because of a // loop caused by a configuration error. // it could cause a "null pointer exception" in AvalonMailRepository - // much - // harder to understand. - if (currentName.length() > 76) { - int count = 0; - int index = 0; - while ((index = currentName.indexOf('!', index + 1)) >= 0) { - count++; - } - // It looks like a configuration loop. It's better to stop. - if (count > 7) { - throw new MessagingException("Unable to create a new message name: too long." + " Possible loop in config.xml."); - } else { - currentName = currentName.substring(0, 76); - } - } + // much harder to understand. + String newName = currentName + generateRandomSuffix(suffixLength, separator); + return stripFirstCharsIfNeeded(nameMaxLength, newName); + } - return currentName + "-!" + random.nextInt(1048576); + private static String stripFirstCharsIfNeeded(int nameMaxLength, String newName) { + return newName.substring(Math.max(0, newName.length() - nameMaxLength)); + } + + private static String generateRandomSuffix(int suffixLength, char separator) { + return "-" + separator + RandomStringUtils.randomNumeric(suffixLength - 2); + } + + private static void detectPossibleLoop(String currentName, int loopThreshold, char separator) throws MessagingException { + long occurrences = currentName.chars().filter(c -> Chars.saturatedCast(c) == separator).count(); + + // It looks like a configuration loop. It's better to stop. + if (occurrences > loopThreshold) { + throw new MessagingException("Unable to create a new message name: too long. Possible loop in config.xml."); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/31707935/server/container/core/src/test/java/org/apache/james/server/core/MailImplTest.java ---------------------------------------------------------------------- diff --git a/server/container/core/src/test/java/org/apache/james/server/core/MailImplTest.java b/server/container/core/src/test/java/org/apache/james/server/core/MailImplTest.java index e90e4d0..49ce62a 100644 --- a/server/container/core/src/test/java/org/apache/james/server/core/MailImplTest.java +++ b/server/container/core/src/test/java/org/apache/james/server/core/MailImplTest.java @@ -191,7 +191,6 @@ public class MailImplTest { } @Test - @Ignore("short value doesn't trigger the assertion") public void deriveNewNameShouldThrowWhenMoreThan8NestedCallsAndSmallInitialValue() throws MessagingException { String called6Times = IntStream.range(0, 8) .mapToObj(String::valueOf) @@ -200,7 +199,6 @@ public class MailImplTest { } @Test - @Ignore("truncation make impossible to detect 8 calls") public void deriveNewNameShouldThrowWhenMoreThan8NestedCallsAndLongInitialValue() throws MessagingException { String called6Times = IntStream.range(0, 8) .mapToObj(String::valueOf) @@ -208,7 +206,6 @@ public class MailImplTest { assertThatThrownBy(() -> MailImpl.deriveNewName(called6Times)).isInstanceOf(MessagingException.class); } - @Test public void deriveNewNameShouldGenerateNotEqualsCurrentName() throws MessagingException { assertThat(MailImpl.deriveNewName("current")).isNotEqualTo("current"); --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org