From 10c8888b0d3bc7c63e096c23d86064facd6a0f02 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 24 Oct 2025 14:11:24 -0700 Subject: [PATCH 01/10] Refactored TestMailmanServer to prepare for V3 variant --- .../bots/mlbridge/LabelsUpdaterTests.java | 4 +- .../MailingListArchiveReaderBotTests.java | 8 +- .../mlbridge/MailingListBridgeBotTests.java | 90 +++++++++--------- .../mailinglist/MailingListNotifierTests.java | 28 +++--- .../skara/mailinglist/MailmanTests.java | 10 +- .../openjdk/skara/test/TestMailmanServer.java | 93 ++++++++++++------- 6 files changed, 130 insertions(+), 103 deletions(-) diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/LabelsUpdaterTests.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/LabelsUpdaterTests.java index 830666f5a..275b58c7c 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/LabelsUpdaterTests.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/LabelsUpdaterTests.java @@ -38,7 +38,7 @@ public class LabelsUpdaterTests { @Test void simple(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); - var listServer = new TestMailmanServer();) { + var listServer = TestMailmanServer.createV2();) { var targetRepo = credentials.getHostedRepository(); var listAddress = EmailAddress.parse(listServer.createList("test")); var mlBot = MailingListBridgeBot.newBuilder() @@ -70,7 +70,7 @@ void simple(TestInfo testInfo) throws IOException { @Test void update(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); - var listServer = new TestMailmanServer();) { + var listServer = TestMailmanServer.createV2();) { var targetRepo = credentials.getHostedRepository(); var listAddress = EmailAddress.parse(listServer.createList("test")); var listAddress2 = EmailAddress.parse(listServer.createList("test2")); diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java index 6ae36d563..4b92f2aab 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java @@ -59,7 +59,7 @@ private void addReply(Conversation conversation, EmailAddress recipient, Mailing void simpleArchive(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -134,7 +134,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { void rememberBridged(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -211,7 +211,7 @@ void rememberBridged(TestInfo testInfo) throws IOException { void largeEmail(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -293,7 +293,7 @@ void largeEmail(TestInfo testInfo) throws IOException { void branchMissing(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java index 8bf64d217..34218d104 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java @@ -111,7 +111,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -307,7 +307,7 @@ void archiveIntegrated(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -400,7 +400,7 @@ void archiveLegacyIntegrated(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -474,7 +474,7 @@ void archiveDirectToIntegrated(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -553,7 +553,7 @@ void archiveIntegratedRetainPrefix(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -630,7 +630,7 @@ void archiveClosed(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -719,7 +719,7 @@ void archiveFailedAutoMerge(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -773,7 +773,7 @@ void reviewComment(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -882,7 +882,7 @@ void combineComments(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -979,7 +979,7 @@ void commentThreading(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1108,7 +1108,7 @@ void commentThreadingSeparated(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1180,7 +1180,7 @@ void commentWithMention(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1244,7 +1244,7 @@ void reviewCommentWithMention(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1309,7 +1309,7 @@ void commentWithQuote(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1374,7 +1374,7 @@ void reviewContext(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1430,7 +1430,7 @@ void multipleReviewContexts(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1506,7 +1506,7 @@ void filterComments(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1595,7 +1595,7 @@ void incrementalChanges(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1706,7 +1706,7 @@ void forcePushed(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository("author"); var main = credentials.getHostedRepository("main"); @@ -1793,7 +1793,7 @@ void rebased(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository("author"); var main = credentials.getHostedRepository("main"); @@ -1887,7 +1887,7 @@ void incrementalAfterRebase(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1966,7 +1966,7 @@ void mergeWebrev(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2052,7 +2052,7 @@ void mergeWebrevConflict(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2124,7 +2124,7 @@ void mergeWebrevNoConflict(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2195,7 +2195,7 @@ void skipAddingExistingWebrev(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2275,7 +2275,7 @@ void notifyReviewVerdicts(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2368,7 +2368,7 @@ void ignoreComments(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var ignored = credentials.getHostedRepository(); @@ -2434,7 +2434,7 @@ void replyToEmptyReview(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -2495,7 +2495,7 @@ void cooldown(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2560,7 +2560,7 @@ void cooldownNewRevision(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2626,7 +2626,7 @@ void retryAfterCooldown(TestInfo testInfo) throws IOException, InterruptedExcept try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2718,7 +2718,7 @@ void branchPrefix(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2775,7 +2775,7 @@ void repoPrefix(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2832,7 +2832,7 @@ void repoAndBranchPrefix(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2890,7 +2890,7 @@ void retryNewRevisionAfterCooldown(TestInfo testInfo) throws IOException, Interr try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2983,7 +2983,7 @@ void multipleRecipients(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3062,7 +3062,7 @@ void jsonArchive(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(false); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3263,7 +3263,7 @@ void rebaseOnRetry(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3351,7 +3351,7 @@ void dependent(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3423,7 +3423,7 @@ void commentWithQuoteFromBridged(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var bridge = credentials.getHostedRepository(); @@ -3499,7 +3499,7 @@ void notArchiveDraftPR(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3676,7 +3676,7 @@ void noWebrev(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3822,7 +3822,7 @@ void mergeWithoutWebrev(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3908,7 +3908,7 @@ void archiveLongBody(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -4002,7 +4002,7 @@ void largeDiffArchive(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); diff --git a/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java b/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java index 2cd3e0bd3..7b7ec537f 100644 --- a/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java +++ b/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java @@ -40,7 +40,7 @@ public class MailingListNotifierTests { @Test void testMailingList(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -114,7 +114,7 @@ void testMailingList(TestInfo testInfo) throws IOException { @Test void testMailingListMultiple(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -191,7 +191,7 @@ void testMailingListMultiple(TestInfo testInfo) throws IOException { @Test void testMailingListMerge(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -271,7 +271,7 @@ void testMailingListMerge(TestInfo testInfo) throws IOException { @Test void testMailingListSponsored(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -336,7 +336,7 @@ void testMailingListSponsored(TestInfo testInfo) throws IOException { @Test void testMailingListMultipleBranches(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -441,7 +441,7 @@ void testMailingListMultipleBranches(TestInfo testInfo) throws IOException { @Test void testMailingListPROnlyMultipleBranches(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -526,7 +526,7 @@ void testMailingListPROnlyMultipleBranches(TestInfo testInfo) throws IOException @Test void testMailingListPR(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -617,7 +617,7 @@ void testMailingListPR(TestInfo testInfo) throws IOException { @Test void testMailingListMergePR(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -715,7 +715,7 @@ void testMailingListMergePR(TestInfo testInfo) throws IOException { @Test void testMailingListPROnce(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -814,7 +814,7 @@ void testMailingListPROnce(TestInfo testInfo) throws IOException { void testMailinglistTag(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer(); + var listServer = TestMailmanServer.createV2(); var scratchFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); var localRepoFolder = tempFolder.path().resolve("repo"); @@ -938,7 +938,7 @@ void testMailinglistTag(TestInfo testInfo) throws IOException { void testMailinglistPlainTags(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = new TestMailmanServer()) { + var listServer = TestMailmanServer.createV2()) { var repo = credentials.getHostedRepository(); var localRepoFolder = tempFolder.path().resolve("repo"); var localRepo = CheckableRepository.init(localRepoFolder, repo.repositoryType()); @@ -1033,7 +1033,7 @@ void testMailinglistPlainTags(TestInfo testInfo) throws IOException { @Test void testMailingListBranch(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -1114,7 +1114,7 @@ void testMailingListBranch(TestInfo testInfo) throws IOException { @Test void testMailingListNoIdempotence(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -1181,7 +1181,7 @@ void testMailingListNoIdempotence(TestInfo testInfo) throws IOException { @Test void testMailingListWithExistingRepo(TestInfo testInfo) throws IOException { - try (var listServer = new TestMailmanServer(); + try (var listServer = TestMailmanServer.createV2(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); diff --git a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/MailmanTests.java b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/MailmanTests.java index 362ad663e..bb7a471ec 100644 --- a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/MailmanTests.java +++ b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/MailmanTests.java @@ -35,7 +35,7 @@ class MailmanTests { @Test void simple() throws IOException { - try (var testServer = new TestMailmanServer()) { + try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO); @@ -60,7 +60,7 @@ void simple() throws IOException { @Test void replies() throws IOException { - try (var testServer = new TestMailmanServer()) { + try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO); @@ -106,7 +106,7 @@ void replies() throws IOException { @Test void cached() throws IOException { - try (var testServer = new TestMailmanServer()) { + try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO, true); @@ -140,7 +140,7 @@ void cached() throws IOException { @Test void interval() throws IOException { - try (var testServer = new TestMailmanServer()) { + try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), Duration.ofDays(1)); @@ -172,7 +172,7 @@ void interval() throws IOException { @Test void poll3months() throws Exception { - try (var testServer = new TestMailmanServer()) { + try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO); diff --git a/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java b/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java index e65815bde..193d0df52 100644 --- a/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java +++ b/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java @@ -36,34 +36,27 @@ import java.util.*; import java.util.regex.Pattern; -public class TestMailmanServer implements AutoCloseable { - private final HttpServer httpServer; +public abstract class TestMailmanServer implements AutoCloseable { + protected final HttpServer httpServer; private final SMTPServer smtpServer; - private final Map> lists = new HashMap<>(); - private int callCount = 0; - private boolean lastResponseCached; - static private final Pattern listPathPattern = Pattern.compile("^/test/(.*?)/(.*)\\.txt"); + public static TestMailmanServer createV2() throws IOException { + return new TestMailman2Server(); + } private class Handler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { callCount++; - var listMatcher = listPathPattern.matcher(exchange.getRequestURI().getPath()); - if (!listMatcher.matches()) { - throw new RuntimeException(); - } - var listPath = listMatcher.group(1); - var datePath = listMatcher.group(2); - var listMap = lists.get(listPath); - if (!listMap.containsKey(datePath)) { + var mboxContents = getMboxContents(exchange); + if (mboxContents == null) { exchange.sendResponseHeaders(404, 0); exchange.close(); return; } - var response = listMap.get(datePath).toString(); + var response = mboxContents.toString(); lastResponseCached = false; try { @@ -91,8 +84,7 @@ public void handle(HttpExchange exchange) throws IOException { } } - public TestMailmanServer() throws IOException - { + protected TestMailmanServer() throws IOException { InetSocketAddress address = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); httpServer = HttpServer.create(address, 0); httpServer.createContext("/test", new Handler()); @@ -102,6 +94,8 @@ public TestMailmanServer() throws IOException smtpServer = new SMTPServer(); } + protected abstract StringBuilder getMboxContents(HttpExchange exchange); + public URI getArchive() { return URIBuilder.base("http://" + httpServer.getAddress().getHostString() + ":" + httpServer.getAddress().getPort() + "/test/").build(); } @@ -110,13 +104,9 @@ public String getSMTP() { return smtpServer.address(); } - public String createList(String name) throws IOException { - var listName = EmailAddress.parse(name + "@" + httpServer.getAddress().getHostString()).toString(); - lists.put(name, new HashMap<>()); - return listName; - } + public abstract String createList(String name); - public void processIncoming(Duration timeout) throws IOException { + public void processIncoming(Duration timeout) { var email = smtpServer.receive(timeout); var subject = email.subject(); if (subject.startsWith("Re: ")) { @@ -127,18 +117,12 @@ public void processIncoming(Duration timeout) throws IOException { .build(); var mboxEntry = Mbox.fromMail(stripped); - var listMap = email.recipients().stream() - .filter(recipient -> lists.containsKey(recipient.localPart())) - .map(recipient -> lists.get(recipient.localPart())) - .findAny().orElseThrow(); - var datePath = DateTimeFormatter.ofPattern("yyyy-MMMM", Locale.US).format(email.date()); - if (!listMap.containsKey(datePath)) { - listMap.put(datePath, new StringBuilder()); - } - listMap.get(datePath).append(mboxEntry); + archiveEmail(email, mboxEntry); } - public void processIncoming() throws IOException { + protected abstract void archiveEmail(Email email, String mboxEntry); + + public void processIncoming() { processIncoming(Duration.ofSeconds(10)); } @@ -160,3 +144,46 @@ public int callCount() { return callCount; } } + +class TestMailman2Server extends TestMailmanServer { + + private static final Pattern listPathPattern = Pattern.compile("^/test/(.*?)/(.*)\\.txt"); + // Map from local part of email list name to map from date string to mbox contents + private final Map> lists = new HashMap<>(); + + public TestMailman2Server() throws IOException { + super(); + } + + @Override + protected void archiveEmail(Email email, String mboxEntry) { + var listMap = email.recipients().stream() + .filter(recipient -> lists.containsKey(recipient.localPart())) + .map(recipient -> lists.get(recipient.localPart())) + .findAny().orElseThrow(); + var datePath = DateTimeFormatter.ofPattern("yyyy-MMMM", Locale.US).format(email.date()); + if (!listMap.containsKey(datePath)) { + listMap.put(datePath, new StringBuilder()); + } + listMap.get(datePath).append(mboxEntry); + } + + @Override + protected StringBuilder getMboxContents(HttpExchange exchange) { + var listMatcher = listPathPattern.matcher(exchange.getRequestURI().getPath()); + if (!listMatcher.matches()) { + throw new RuntimeException(); + } + var listPath = listMatcher.group(1); + var datePath = listMatcher.group(2); + var listMap = lists.get(listPath); + return listMap.get(datePath); + } + + @Override + public String createList(String name) { + var listName = EmailAddress.parse(name + "@" + httpServer.getAddress().getHostString()).toString(); + lists.put(name, new HashMap<>()); + return listName; + } +} From 7ec9c34e69262e4ca3644713697c9b2e295a54bd Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Tue, 28 Oct 2025 13:54:58 -0700 Subject: [PATCH 02/10] Tests are passing --- .../skara/bots/mlbridge/ArchiveWorkItem.java | 2 +- .../mlbridge/MailingListBridgeBotFactory.java | 2 +- .../MailingListArchiveReaderBotTests.java | 14 +- .../mlbridge/MailingListBridgeBotTests.java | 116 ++++---- .../MailingListNotifierFactory.java | 2 +- .../mailinglist/MailingListNotifierTests.java | 56 ++-- .../mailinglist/MailingListServerFactory.java | 19 +- .../mailinglist/mailman/Mailman2Server.java | 27 ++ .../mailinglist/mailman/Mailman3Server.java | 22 ++ .../mailman/MailmanListReader.java | 174 +++++++++--- .../mailinglist/mailman/MailmanServer.java | 18 +- .../{MailmanTests.java => Mailman2Tests.java} | 12 +- .../mailinglist/Mailman3IntegrationTests.java | 31 +++ .../skara/mailinglist/Mailman3Tests.java | 255 ++++++++++++++++++ .../openjdk/skara/test/TestMailmanServer.java | 102 ++++++- 15 files changed, 682 insertions(+), 170 deletions(-) create mode 100644 mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java create mode 100644 mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java rename mailinglist/src/test/java/org/openjdk/skara/mailinglist/{MailmanTests.java => Mailman2Tests.java} (97%) create mode 100644 mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java create mode 100644 mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java index 1cd389646..60d9823f1 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java @@ -378,7 +378,7 @@ public Collection run(Path scratchPath) { var jsonWebrevPath = scratchPath.resolve("mlbridge-webrevs").resolve("json"); var htmlWebrevPath = scratchPath.resolve("mlbridge-webrevs").resolve("html"); - var listServer = MailingListServerFactory.createMailmanServer(bot.listArchive(), bot.smtpServer(), bot.sendInterval()); + var listServer = MailingListServerFactory.createMailman2Server(bot.listArchive(), bot.smtpServer(), bot.sendInterval()); var archiver = new ReviewArchive(pr, bot.emailAddress()); var lastDraftTime = pr.lastMarkedAsDraftTime().orElse(null); diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java index f45acdeeb..6b424bd5a 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java @@ -101,7 +101,7 @@ public List create(BotConfiguration configuration) { if (specific.get("server").contains("etag")) { useEtag = specific.get("server").get("etag").asBoolean(); } - var mailmanServer = MailingListServerFactory.createMailmanServer(listArchive, listSmtp, Duration.ZERO, useEtag); + var mailmanServer = MailingListServerFactory.createMailman2Server(listArchive, listSmtp, Duration.ZERO, useEtag); var mailingListReaderMap = new HashMap, MailingListReader>(); diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java index 4b92f2aab..f465c2009 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java @@ -59,7 +59,7 @@ private void addReply(Conversation conversation, EmailAddress recipient, Mailing void simpleArchive(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -85,7 +85,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { .build(); // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var readerBot = new MailingListArchiveReaderBot(mailmanList, archive); @@ -134,7 +134,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { void rememberBridged(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -161,7 +161,7 @@ void rememberBridged(TestInfo testInfo) throws IOException { .build(); // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var readerBot = new MailingListArchiveReaderBot(mailmanList, archive); @@ -211,7 +211,7 @@ void rememberBridged(TestInfo testInfo) throws IOException { void largeEmail(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -237,7 +237,7 @@ void largeEmail(TestInfo testInfo) throws IOException { .build(); // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var readerBot = new MailingListArchiveReaderBot(mailmanList, archive); @@ -293,7 +293,7 @@ void largeEmail(TestInfo testInfo) throws IOException { void branchMissing(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java index 34218d104..f6bdedfd5 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java @@ -111,7 +111,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -230,7 +230,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -307,7 +307,7 @@ void archiveIntegrated(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -400,7 +400,7 @@ void archiveLegacyIntegrated(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -474,7 +474,7 @@ void archiveDirectToIntegrated(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -553,7 +553,7 @@ void archiveIntegratedRetainPrefix(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -630,7 +630,7 @@ void archiveClosed(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -719,7 +719,7 @@ void archiveFailedAutoMerge(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -773,7 +773,7 @@ void reviewComment(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -835,7 +835,7 @@ void reviewComment(TestInfo testInfo) throws IOException { assertFalse(archiveContains(archiveFolder.path(), "Don't mind me")); // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -882,7 +882,7 @@ void combineComments(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -936,7 +936,7 @@ void combineComments(TestInfo testInfo) throws IOException { assertEquals(2, archiveContainsCount(archiveFolder.path(), "^On.*wrote:")); // As well as the mailing list - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -979,7 +979,7 @@ void commentThreading(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1057,7 +1057,7 @@ void commentThreading(TestInfo testInfo) throws IOException { assertTrue(archiveText.indexOf("Looks fine") < archiveText.indexOf("The final review comment")); // Check the mailing list - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1108,7 +1108,7 @@ void commentThreadingSeparated(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1180,7 +1180,7 @@ void commentWithMention(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1244,7 +1244,7 @@ void reviewCommentWithMention(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1309,7 +1309,7 @@ void commentWithQuote(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -1374,7 +1374,7 @@ void reviewContext(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1430,7 +1430,7 @@ void multipleReviewContexts(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1506,7 +1506,7 @@ void filterComments(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1595,7 +1595,7 @@ void incrementalChanges(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1667,7 +1667,7 @@ void incrementalChanges(TestInfo testInfo) throws IOException { assertEquals(1, webrevComments.size()); // Check that sender address is set properly - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1706,7 +1706,7 @@ void forcePushed(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository("author"); var main = credentials.getHostedRepository("main"); @@ -1775,7 +1775,7 @@ void forcePushed(TestInfo testInfo) throws IOException { assertEquals(1, webrevComments.size()); // Check that sender address is set properly - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1793,7 +1793,7 @@ void rebased(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository("author"); var main = credentials.getHostedRepository("main"); @@ -1869,7 +1869,7 @@ void rebased(TestInfo testInfo) throws IOException { assertEquals(1, webrevComments.size()); // Check that sender address is set properly - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1887,7 +1887,7 @@ void incrementalAfterRebase(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -1966,7 +1966,7 @@ void mergeWebrev(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2052,7 +2052,7 @@ void mergeWebrevConflict(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2124,7 +2124,7 @@ void mergeWebrevNoConflict(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2195,7 +2195,7 @@ void skipAddingExistingWebrev(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2275,7 +2275,7 @@ void notifyReviewVerdicts(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2344,7 +2344,7 @@ void notifyReviewVerdicts(TestInfo testInfo) throws IOException { listServer.processIncoming(); listServer.processIncoming(); listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertTrue(conversations.get(0).allMessages().get(1).body().contains("hosted.git/pr/1/review/0")); @@ -2368,7 +2368,7 @@ void ignoreComments(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var ignored = credentials.getHostedRepository(); @@ -2434,7 +2434,7 @@ void replyToEmptyReview(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var reviewer = credentials.getHostedRepository(); @@ -2495,7 +2495,7 @@ void cooldown(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2560,7 +2560,7 @@ void cooldownNewRevision(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2626,7 +2626,7 @@ void retryAfterCooldown(TestInfo testInfo) throws IOException, InterruptedExcept try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2718,7 +2718,7 @@ void branchPrefix(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2775,7 +2775,7 @@ void repoPrefix(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2832,7 +2832,7 @@ void repoAndBranchPrefix(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -2890,7 +2890,7 @@ void retryNewRevisionAfterCooldown(TestInfo testInfo) throws IOException, Interr try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var bot = credentials.getHostedRepository(); var author = credentials.getHostedRepository(); @@ -2983,7 +2983,7 @@ void multipleRecipients(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3027,7 +3027,7 @@ void multipleRecipients(TestInfo testInfo) throws IOException { listServer.processIncoming(); // The mail should have been sent to list1 - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress1.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -3062,7 +3062,7 @@ void jsonArchive(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(false); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3159,7 +3159,7 @@ void jsonArchive(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -3263,7 +3263,7 @@ void rebaseOnRetry(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3351,7 +3351,7 @@ void dependent(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3423,7 +3423,7 @@ void commentWithQuoteFromBridged(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var bridge = credentials.getHostedRepository(); @@ -3499,7 +3499,7 @@ void notArchiveDraftPR(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3676,7 +3676,7 @@ void noWebrev(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3771,7 +3771,7 @@ void noWebrev(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -3822,7 +3822,7 @@ void mergeWithoutWebrev(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3908,7 +3908,7 @@ void archiveLongBody(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -3980,7 +3980,7 @@ void archiveLongBody(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -4002,7 +4002,7 @@ void largeDiffArchive(TestInfo testInfo) throws IOException { var tempFolder = new TemporaryDirectory(); var archiveFolder = new TemporaryDirectory(); var webrevFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var webrevServer = new TestWebrevServer()) { var author = credentials.getHostedRepository(); var archive = credentials.getHostedRepository(); @@ -4063,7 +4063,7 @@ void largeDiffArchive(TestInfo testInfo) throws IOException { assertTrue(pr.store().comments().get(1).body().contains("[Full](Webrev is not available because diff is too large)")); // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java index 9c8576e1b..849291c3f 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java @@ -45,7 +45,7 @@ public Notifier create(BotConfiguration botConfiguration, JSONObject notifierCon var sender = EmailAddress.parse(notifierConfiguration.get("sender").asString()); var archive = URIBuilder.base(notifierConfiguration.get("archive").asString()).build(); var interval = notifierConfiguration.contains("interval") ? Duration.parse(notifierConfiguration.get("interval").asString()) : Duration.ofSeconds(1); - var listServer = MailingListServerFactory.createMailmanServer(archive, smtp, interval); + var listServer = MailingListServerFactory.createMailman2Server(archive, smtp, interval); var recipient = notifierConfiguration.get("recipient").asString(); var recipientAddress = EmailAddress.parse(recipient); diff --git a/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java b/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java index 7b7ec537f..9eaa8c41f 100644 --- a/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java +++ b/bots/notify/src/test/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierTests.java @@ -40,7 +40,7 @@ public class MailingListNotifierTests { @Test void testMailingList(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -51,7 +51,7 @@ void testMailingList(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -114,7 +114,7 @@ void testMailingList(TestInfo testInfo) throws IOException { @Test void testMailingListMultiple(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -125,7 +125,7 @@ void testMailingListMultiple(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -191,7 +191,7 @@ void testMailingListMultiple(TestInfo testInfo) throws IOException { @Test void testMailingListMerge(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -202,7 +202,7 @@ void testMailingListMerge(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -271,7 +271,7 @@ void testMailingListMerge(TestInfo testInfo) throws IOException { @Test void testMailingListSponsored(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -282,7 +282,7 @@ void testMailingListSponsored(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -336,7 +336,7 @@ void testMailingListSponsored(TestInfo testInfo) throws IOException { @Test void testMailingListMultipleBranches(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -348,7 +348,7 @@ void testMailingListMultipleBranches(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -441,7 +441,7 @@ void testMailingListMultipleBranches(TestInfo testInfo) throws IOException { @Test void testMailingListPROnlyMultipleBranches(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -452,7 +452,7 @@ void testMailingListPROnlyMultipleBranches(TestInfo testInfo) throws IOException localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -526,7 +526,7 @@ void testMailingListPROnlyMultipleBranches(TestInfo testInfo) throws IOException @Test void testMailingListPR(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -537,7 +537,7 @@ void testMailingListPR(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -617,7 +617,7 @@ void testMailingListPR(TestInfo testInfo) throws IOException { @Test void testMailingListMergePR(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -628,7 +628,7 @@ void testMailingListMergePR(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -715,7 +715,7 @@ void testMailingListMergePR(TestInfo testInfo) throws IOException { @Test void testMailingListPROnce(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -727,7 +727,7 @@ void testMailingListPROnce(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -814,7 +814,7 @@ void testMailingListPROnce(TestInfo testInfo) throws IOException { void testMailinglistTag(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2(); + var listServer = TestMailmanServer.createV3(); var scratchFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); var localRepoFolder = tempFolder.path().resolve("repo"); @@ -825,7 +825,7 @@ void testMailinglistTag(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -938,7 +938,7 @@ void testMailinglistTag(TestInfo testInfo) throws IOException { void testMailinglistPlainTags(TestInfo testInfo) throws IOException { try (var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory(); - var listServer = TestMailmanServer.createV2()) { + var listServer = TestMailmanServer.createV3()) { var repo = credentials.getHostedRepository(); var localRepoFolder = tempFolder.path().resolve("repo"); var localRepo = CheckableRepository.init(localRepoFolder, repo.repositoryType()); @@ -948,7 +948,7 @@ void testMailinglistPlainTags(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -1033,7 +1033,7 @@ void testMailinglistPlainTags(TestInfo testInfo) throws IOException { @Test void testMailingListBranch(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -1045,7 +1045,7 @@ void testMailingListBranch(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -1114,7 +1114,7 @@ void testMailingListBranch(TestInfo testInfo) throws IOException { @Test void testMailingListNoIdempotence(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -1125,7 +1125,7 @@ void testMailingListNoIdempotence(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); @@ -1181,7 +1181,7 @@ void testMailingListNoIdempotence(TestInfo testInfo) throws IOException { @Test void testMailingListWithExistingRepo(TestInfo testInfo) throws IOException { - try (var listServer = TestMailmanServer.createV2(); + try (var listServer = TestMailmanServer.createV3(); var credentials = new HostCredentials(testInfo); var tempFolder = new TemporaryDirectory()) { var repo = credentials.getHostedRepository(); @@ -1192,7 +1192,7 @@ void testMailingListWithExistingRepo(TestInfo testInfo) throws IOException { localRepo.pushAll(repo.authenticatedUrl()); var listAddress = EmailAddress.parse(listServer.createList("test")); - var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var tagStorage = createTagStorage(repo); var branchStorage = createBranchStorage(repo); diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java index e8fcd022c..3f29f0aa0 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java @@ -22,7 +22,8 @@ */ package org.openjdk.skara.mailinglist; -import org.openjdk.skara.mailinglist.mailman.MailmanServer; +import org.openjdk.skara.mailinglist.mailman.Mailman2Server; +import org.openjdk.skara.mailinglist.mailman.Mailman3Server; import org.openjdk.skara.mailinglist.mboxfile.MboxFileListServer; import java.net.URI; @@ -30,12 +31,20 @@ import java.time.Duration; public class MailingListServerFactory { - public static MailingListServer createMailmanServer(URI archive, String smtp, Duration sendInterval) { - return new MailmanServer(archive, smtp, sendInterval, false); + public static MailingListServer createMailman2Server(URI archive, String smtp, Duration sendInterval) { + return new Mailman2Server(archive, smtp, sendInterval, false); } - public static MailingListServer createMailmanServer(URI archive, String smtp, Duration sendInterval, boolean useEtag) { - return new MailmanServer(archive, smtp, sendInterval, useEtag); + public static MailingListServer createMailman2Server(URI archive, String smtp, Duration sendInterval, boolean useEtag) { + return new Mailman2Server(archive, smtp, sendInterval, useEtag); + } + + public static MailingListServer createMailman3Server(URI archive, String smtp, Duration sendInterval) { + return new Mailman3Server(archive, smtp, sendInterval, false); + } + + public static MailingListServer createMailman3Server(URI archive, String smtp, Duration sendInterval, boolean useEtag) { + return new Mailman3Server(archive, smtp, sendInterval, useEtag); } public static MailingListServer createMboxFileServer(Path file) { diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java new file mode 100644 index 000000000..5fd5876fd --- /dev/null +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java @@ -0,0 +1,27 @@ +package org.openjdk.skara.mailinglist.mailman; + +import java.net.URI; +import java.time.Duration; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.Locale; +import org.openjdk.skara.mailinglist.MailingListReader; +import org.openjdk.skara.network.URIBuilder; + +public class Mailman2Server extends MailmanServer { + + public Mailman2Server(URI archive, String smtpServer, Duration sendInterval, boolean useEtag) { + super(archive, smtpServer, sendInterval, useEtag); + } + + URI getMboxUri(String listName, ZonedDateTime month) { + var dateStr = DateTimeFormatter.ofPattern("yyyy-MMMM", Locale.US).format(month); + return URIBuilder.base(archive).appendPath(listName + "/" + dateStr + ".txt").build(); + } + + @Override + public MailingListReader getListReader(String... listNames) { + return new Mailman2ListReader(this, Arrays.asList(listNames), useEtag); + } +} diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java new file mode 100644 index 000000000..fa86d9ab9 --- /dev/null +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java @@ -0,0 +1,22 @@ +package org.openjdk.skara.mailinglist.mailman; + +import java.net.URI; +import java.time.Duration; +import java.util.Arrays; +import org.openjdk.skara.mailinglist.MailingListReader; + +public class Mailman3Server extends MailmanServer { + + public Mailman3Server(URI archive, String smtpServer, Duration sendInterval, boolean useEtag) { + super(archive, smtpServer, sendInterval, useEtag); + } + + URI getArchiveUri() { + return archive; + } + + @Override + public MailingListReader getListReader(String... listNames) { + return new Mailman3ListReader(this, Arrays.asList(listNames), useEtag); + } +} diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java index 4e33251f5..d8402a449 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java @@ -22,6 +22,10 @@ */ package org.openjdk.skara.mailinglist.mailman; +import java.nio.charset.StandardCharsets; +import java.time.format.DateTimeFormatter; +import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; import org.openjdk.skara.email.*; import org.openjdk.skara.mailinglist.*; @@ -34,14 +38,14 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import org.openjdk.skara.metrics.Counter; +import org.openjdk.skara.network.URIBuilder; -public class MailmanListReader implements MailingListReader { - private final MailmanServer server; +public abstract class MailmanListReader implements MailingListReader { private final boolean useEtag; - private final List names = new ArrayList<>(); + protected final List names = new ArrayList<>(); private final Logger log = Logger.getLogger("org.openjdk.skara.mailinglist"); - private final ConcurrentMap> pageCache = new ConcurrentHashMap<>(); - private List cachedConversations = new ArrayList<>(); + protected final ConcurrentMap> pageCache = new ConcurrentHashMap<>(); + protected List cachedConversations = new ArrayList<>(); private static final HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); @@ -49,8 +53,7 @@ public class MailmanListReader implements MailingListReader { private static final Counter.WithOneLabel POLLING_COUNTER = Counter.name("skara_mailman_polling").labels("code").register(); - MailmanListReader(MailmanServer server, Collection names, boolean useEtag) { - this.server = server; + MailmanListReader(Collection names, boolean useEtag) { this.useEtag = useEtag; for (var name : names) { if (name.contains("@")) { @@ -61,29 +64,7 @@ public class MailmanListReader implements MailingListReader { } } - @Override - public String toString() { - return "MailmanList:" + String.join(", ", names); - } - - private List getMonthRange(Duration maxAge) { - var now = ZonedDateTime.now(); - var start = now.minus(maxAge); - List ret = new ArrayList<>(); - - // Iterate all the way until start is equal to now - while (!start.isAfter(now)) { - ret.add(start); - var next = start.plus(Duration.ofDays(1)); - while (start.getMonthValue() == next.getMonthValue()) { - next = next.plus(Duration.ofDays(1)); - } - start = next; - } - return ret; - } - - private Optional> getPage(URI uri) { + protected Optional> getPage(URI uri) { var requestBuilder = HttpRequest.newBuilder(uri) .timeout(Duration.ofSeconds(30)) .GET(); @@ -96,7 +77,7 @@ private Optional> getPage(URI uri) { var request = requestBuilder.build(); try { - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); POLLING_COUNTER.labels(String.valueOf(response.statusCode())).inc(); if (response.statusCode() == 200) { pageCache.put(uri, response); @@ -118,34 +99,73 @@ private Optional> getPage(URI uri) { } } + protected void updateCachedConversations(ArrayList emails, Duration maxAge) { + var conversations = Mbox.parseMbox(emails); + var threshold = ZonedDateTime.now().minus(maxAge); + cachedConversations = conversations.stream() + .filter(mail -> mail.first().date().isAfter(threshold)) + .collect(Collectors.toList()); + } +} + +class Mailman2ListReader extends MailmanListReader { + private final Mailman2Server server; + + Mailman2ListReader(Mailman2Server server, Collection names, boolean useEtag) { + super(names, useEtag); + this.server = server; + } + + @Override + public String toString() { + return "Mailman2List:" + String.join(", ", names); + } + + private List getMonthRange(Duration maxAge) { + var now = ZonedDateTime.now(); + var start = now.minus(maxAge); + List ret = new ArrayList<>(); + + // Iterate all the way until start is equal to now + while (!start.isAfter(now)) { + ret.add(start); + var next = start.plus(Duration.ofDays(1)); + while (start.getMonthValue() == next.getMonthValue()) { + next = next.plus(Duration.ofDays(1)); + } + start = next; + } + return ret; + } + @Override public List conversations(Duration maxAge) { // Order pages by most recent first var potentialPages = getMonthRange(maxAge).stream() .sorted(Comparator.reverseOrder()) - .collect(Collectors.toList()); + .toList(); var monthCount = 0; var newContent = false; var emails = new ArrayList(); for (var month : potentialPages) { for (var name : names) { - URI mboxUri = server.getMbox(name, month); + URI mboxUri = server.getMboxUri(name, month); var sender = EmailAddress.from(name + "@" + mboxUri.getHost()); // For archives older than the previous month, always use cached results if (monthCount > 1 && pageCache.containsKey(mboxUri)) { var cachedResponse = pageCache.get(mboxUri); if (cachedResponse != null && cachedResponse.statusCode() != 404) { - emails.addAll(0, Mbox.splitMbox(cachedResponse.body(), sender)); + emails.addAll(0, Mbox.splitMbox(new String(cachedResponse.body(), StandardCharsets.UTF_8), sender)); } } else { var mboxResponse = getPage(mboxUri); if (mboxResponse.isPresent()) { if (mboxResponse.get().statusCode() == 304) { - emails.addAll(0, Mbox.splitMbox(pageCache.get(mboxUri).body(), sender)); + emails.addAll(0, Mbox.splitMbox(new String(pageCache.get(mboxUri).body(), StandardCharsets.UTF_8), sender)); } else { - emails.addAll(0, Mbox.splitMbox(mboxResponse.get().body(), sender)); + emails.addAll(0, Mbox.splitMbox(new String(mboxResponse.get().body(), StandardCharsets.UTF_8), sender)); newContent = true; } } @@ -155,13 +175,85 @@ public List conversations(Duration maxAge) { } if (newContent) { - var conversations = Mbox.parseMbox(emails); - var threshold = ZonedDateTime.now().minus(maxAge); - cachedConversations = conversations.stream() - .filter(mail -> mail.first().date().isAfter(threshold)) - .collect(Collectors.toList()); + updateCachedConversations(emails, maxAge); } return cachedConversations; } } + +class Mailman3ListReader extends MailmanListReader { + private final Mailman3Server server; + + Mailman3ListReader(Mailman3Server server, Collection names, boolean useEtag) { + super(names, useEtag); + this.server = server; + } + + @Override + public List conversations(Duration maxAge) { + var now = ZonedDateTime.now(); + var start = now.minus(maxAge).withDayOfMonth(1); + var query = Map.of("start", List.of(start.format(DateTimeFormatter.ISO_LOCAL_DATE))); + var emails = new ArrayList(); + var newContent = false; + // https://mail-dev.example.com/archives/list/skara-test@mail-dev.example.com/export/foo.mbox.gz?start=2024-10-25&end=2025-10-25 + for (String name : names) { + var mboxUri = URIBuilder.base(server.getArchiveUri()).appendPath("list/").appendPath(name) + .appendPath("@").appendPath(server.getArchiveUri().getHost()) + .appendPath("/export/foo.mbox.gz").setQuery(query).build(); + var mboxResponse = getPage(mboxUri); + if (mboxResponse.isPresent()) { + var sender = EmailAddress.from(name + "@" + server.getArchiveUri().getHost()); + if (mboxResponse.get().statusCode() == 304) { + emails.addAll(0, Mbox.splitMbox(gunzipToString(pageCache.get(mboxUri).body()), sender)); + } else { + emails.addAll(0, Mbox.splitMbox(gunzipToString(mboxResponse.get().body()), sender)); + newContent = true; + } + } + } + + if (newContent) { + updateCachedConversations(emails, maxAge); + } + + return cachedConversations; + } + + private String gunzipToString(byte[] data) { + try (var in = new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(data)), StandardCharsets.UTF_8)) { + var out = new StringBuilderWriter(); + in.transferTo(out); + return out.toString(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * Simple StringWriter clone that uses a StringBuilder instead of a StringBuffer. + */ + private static class StringBuilderWriter extends Writer { + + private final StringBuilder buf = new StringBuilder(); + + @Override + public String toString() { + return buf.toString(); + } + + @Override + public void write(char[] cbuf, int off, int len) { + buf.append(cbuf, off, len); + } + + @Override + public void flush() { + } + + @Override + public void close() { + } + } +} diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java index 7ac452ee8..7b85a2cce 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java @@ -32,14 +32,14 @@ import java.time.format.DateTimeFormatter; import java.util.*; -public class MailmanServer implements MailingListServer { - private final URI archive; +public abstract class MailmanServer implements MailingListServer { + protected final URI archive; private final String smtpServer; private final Duration sendInterval; - private final boolean useEtag; + protected final boolean useEtag; private volatile Instant lastSend; - public MailmanServer(URI archive, String smtpServer, Duration sendInterval, boolean useEtag) { + protected MailmanServer(URI archive, String smtpServer, Duration sendInterval, boolean useEtag) { this.archive = archive; this.smtpServer = smtpServer; this.sendInterval = sendInterval; @@ -47,11 +47,6 @@ public MailmanServer(URI archive, String smtpServer, Duration sendInterval, bool lastSend = Instant.EPOCH; } - URI getMbox(String listName, ZonedDateTime month) { - var dateStr = DateTimeFormatter.ofPattern("yyyy-MMMM", Locale.US).format(month); - return URIBuilder.base(archive).appendPath(listName + "/" + dateStr + ".txt").build(); - } - void sendMessage(Email message) { while (lastSend.plus(sendInterval).isAfter(Instant.now())) { try { @@ -71,9 +66,4 @@ void sendMessage(Email message) { public void post(Email email) { sendMessage(email); } - - @Override - public MailingListReader getListReader(String... listNames) { - return new MailmanListReader(this, Arrays.asList(listNames), useEtag); - } } diff --git a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/MailmanTests.java b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman2Tests.java similarity index 97% rename from mailinglist/src/test/java/org/openjdk/skara/mailinglist/MailmanTests.java rename to mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman2Tests.java index bb7a471ec..cefc0f29e 100644 --- a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/MailmanTests.java +++ b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman2Tests.java @@ -32,12 +32,12 @@ import static org.junit.jupiter.api.Assertions.*; -class MailmanTests { +class Mailman2Tests { @Test void simple() throws IOException { try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); - var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), + var mailmanServer = MailingListServerFactory.createMailman2Server(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress); var sender = EmailAddress.from("Test", "test@test.email"); @@ -62,7 +62,7 @@ void simple() throws IOException { void replies() throws IOException { try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); - var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), + var mailmanServer = MailingListServerFactory.createMailman2Server(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress); var sender = EmailAddress.from("Test", "test@test.email"); @@ -108,7 +108,7 @@ void replies() throws IOException { void cached() throws IOException { try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); - var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), + var mailmanServer = MailingListServerFactory.createMailman2Server(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO, true); var mailmanList = mailmanServer.getListReader(listAddress); var sender = EmailAddress.from("Test", "test@test.email"); @@ -142,7 +142,7 @@ void cached() throws IOException { void interval() throws IOException { try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); - var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), testServer.getSMTP(), + var mailmanServer = MailingListServerFactory.createMailman2Server(testServer.getArchive(), testServer.getSMTP(), Duration.ofDays(1)); var mailmanList = mailmanServer.getListReader(listAddress); var sender = EmailAddress.from("Test", "test@test.email"); @@ -174,7 +174,7 @@ void interval() throws IOException { void poll3months() throws Exception { try (var testServer = TestMailmanServer.createV2()) { var listAddress = testServer.createList("test"); - var mailmanServer = MailingListServerFactory.createMailmanServer(testServer.getArchive(), + var mailmanServer = MailingListServerFactory.createMailman2Server(testServer.getArchive(), testServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress); var sender = EmailAddress.from("Test", "test@test.email"); diff --git a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java new file mode 100644 index 000000000..f4a8cd73a --- /dev/null +++ b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java @@ -0,0 +1,31 @@ +package org.openjdk.skara.mailinglist; + +import java.time.Duration; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.openjdk.skara.network.URIBuilder; +import org.openjdk.skara.test.EnabledIfTestProperties; +import org.openjdk.skara.test.TestProperties; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +public class Mailman3IntegrationTests { + + private static TestProperties props; + + @BeforeAll + static void beforeAll() { + props = TestProperties.load(); + } + + @Test + @EnabledIfTestProperties({"mailman3.url", "mailman3.list"}) + void testReviews() { + var url = props.get("mailman3.url"); + var listName = props.get("mailman3.list"); + var mailmanServer = MailingListServerFactory.createMailman3Server(URIBuilder.base(url).build(), null, null); + var listReader = mailmanServer.getListReader(listName); + var conversations = listReader.conversations(Duration.ofDays(365)); + assertFalse(conversations.isEmpty()); + } +} diff --git a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java new file mode 100644 index 000000000..397be4187 --- /dev/null +++ b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.skara.mailinglist; + +import java.io.IOException; +import java.time.Duration; +import java.time.ZonedDateTime; +import org.junit.jupiter.api.Test; +import org.openjdk.skara.email.Email; +import org.openjdk.skara.email.EmailAddress; +import org.openjdk.skara.test.TestMailmanServer; + +import static org.junit.jupiter.api.Assertions.*; + +class Mailman3Tests { + @Test + void simple() throws IOException { + try (var testServer = TestMailmanServer.createV3()) { + var listAddress = testServer.createList("test"); + var mailmanServer = MailingListServerFactory.createMailman3Server(testServer.getArchive(), testServer.getSMTP(), + Duration.ZERO); + var mailmanList = mailmanServer.getListReader(listAddress); + var sender = EmailAddress.from("Test", "test@test.email"); + var mail = Email.create(sender, "Subject", "Body") + .recipient(EmailAddress.parse(listAddress)) + .build(); + mailmanServer.post(mail); + var expectedMail = Email.from(mail) + .sender(EmailAddress.parse(listAddress)) + .build(); + + testServer.processIncoming(); + + var conversations = mailmanList.conversations(Duration.ofDays(1)); + assertEquals(1, conversations.size()); + var conversation = conversations.get(0); + assertEquals(expectedMail, conversation.first()); + } + } + + @Test + void replies() throws IOException { + try (var testServer = TestMailmanServer.createV3()) { + var listAddress = testServer.createList("test"); + var mailmanServer = MailingListServerFactory.createMailman3Server(testServer.getArchive(), testServer.getSMTP(), + Duration.ZERO); + var mailmanList = mailmanServer.getListReader(listAddress); + var sender = EmailAddress.from("Test", "test@test.email"); + var sentParent = Email.create(sender, "Subject", "Body") + .recipient(EmailAddress.parse(listAddress)) + .build(); + mailmanServer.post(sentParent); + testServer.processIncoming(); + var expectedParent = Email.from(sentParent) + .sender(EmailAddress.parse(listAddress)) + .build(); + + var conversations = mailmanList.conversations(Duration.ofDays(1)); + assertEquals(1, conversations.size()); + var conversation = conversations.get(0); + assertEquals(expectedParent, conversation.first()); + + var replier = EmailAddress.from("Replier", "replier@test.email"); + var sentReply = Email.create(replier, "Reply subject", "Reply body") + .recipient(EmailAddress.parse(listAddress)) + .header("In-Reply-To", sentParent.id().toString()) + .build(); + mailmanServer.post(sentReply); + var expectedReply = Email.from(sentReply) + .sender(EmailAddress.parse(listAddress)) + .build(); + + testServer.processIncoming(); + + conversations = mailmanList.conversations(Duration.ofDays(1)); + assertEquals(1, conversations.size()); + conversation = conversations.get(0); + assertEquals(expectedParent, conversation.first()); + + var replies = conversation.replies(conversation.first()); + assertEquals(1, replies.size()); + var reply = replies.get(0); + assertEquals(expectedReply, reply); + } + } + + @Test + void cached() throws IOException { + try (var testServer = TestMailmanServer.createV3()) { + var listAddress = testServer.createList("test"); + var mailmanServer = MailingListServerFactory.createMailman3Server(testServer.getArchive(), testServer.getSMTP(), + Duration.ZERO, true); + var mailmanList = mailmanServer.getListReader(listAddress); + var sender = EmailAddress.from("Test", "test@test.email"); + var mail = Email.create(sender, "Subject", "Body") + .recipient(EmailAddress.parse(listAddress)) + .build(); + mailmanServer.post(mail); + testServer.processIncoming(); + + var expectedMail = Email.from(mail) + .sender(EmailAddress.parse(listAddress)) + .build(); + { + var conversations = mailmanList.conversations(Duration.ofDays(1)); + assertEquals(1, conversations.size()); + var conversation = conversations.get(0); + assertEquals(expectedMail, conversation.first()); + assertFalse(testServer.lastResponseCached()); + } + { + var conversations = mailmanList.conversations(Duration.ofDays(1)); + assertEquals(1, conversations.size()); + var conversation = conversations.get(0); + assertEquals(expectedMail, conversation.first()); + assertTrue(testServer.lastResponseCached()); + } + } + } + + @Test + void interval() throws IOException { + try (var testServer = TestMailmanServer.createV3()) { + var listAddress = testServer.createList("test"); + var mailmanServer = MailingListServerFactory.createMailman3Server(testServer.getArchive(), testServer.getSMTP(), + Duration.ofDays(1)); + var mailmanList = mailmanServer.getListReader(listAddress); + var sender = EmailAddress.from("Test", "test@test.email"); + var mail1 = Email.create(sender, "Subject 1", "Body 1") + .recipient(EmailAddress.parse(listAddress)) + .build(); + var mail2 = Email.create(sender, "Subject 2", "Body 2") + .recipient(EmailAddress.parse(listAddress)) + .build(); + new Thread(() -> { + mailmanServer.post(mail1); + mailmanServer.post(mail2); + }).start(); + var expectedMail = Email.from(mail1) + .sender(EmailAddress.parse(listAddress)) + .build(); + + testServer.processIncoming(); + assertThrows(RuntimeException.class, () -> testServer.processIncoming(Duration.ZERO)); + + var conversations = mailmanList.conversations(Duration.ofDays(1)); + assertEquals(1, conversations.size()); + var conversation = conversations.get(0); + assertEquals(expectedMail, conversation.first()); + } + } + + @Test + void poll3months() throws Exception { + try (var testServer = TestMailmanServer.createV3()) { + var listAddress = testServer.createList("test"); + var mailmanServer = MailingListServerFactory.createMailman3Server(testServer.getArchive(), + testServer.getSMTP(), Duration.ZERO); + var mailmanList = mailmanServer.getListReader(listAddress); + var sender = EmailAddress.from("Test", "test@test.email"); + var now = ZonedDateTime.now(); + var mail2monthsAgo = Email.create(sender, "Subject 2 months ago", "Body 1") + .recipient(EmailAddress.parse(listAddress)) + .date(now.minusMonths(2)) + .build(); + var mail1monthAgo = Email.create(sender, "Subject 1 month ago", "Body 2") + .recipient(EmailAddress.parse(listAddress)) + .date(now.minusMonths(1)) + .build(); + var mailNow = Email.create(sender, "Subject now", "Body 3") + .recipient(EmailAddress.parse(listAddress)) + .build(); + + var duration2Months = Duration.between(now.minusMonths(2), now); + { + var conversations = mailmanList.conversations(duration2Months); + assertEquals(0, conversations.size()); + assertEquals(1, testServer.callCount(), "Server wasn't called once"); + } + { + // A 2 months old mail should not be picked up now as old results should be cached + mailmanServer.post(mail2monthsAgo); + testServer.processIncoming(); + testServer.resetCallCount(); + var conversations = mailmanList.conversations(duration2Months); + assertEquals(0, conversations.size()); + // + assertEquals(1, testServer.callCount(), "Server wasn't called once"); + } + { + // A mail from last month should be found + mailmanServer.post(mail1monthAgo); + testServer.processIncoming(); + testServer.resetCallCount(); + var conversations = mailmanList.conversations(duration2Months); + assertEquals(1, conversations.size()); + assertEquals(1, testServer.callCount()); + } + { + // A current mail should be found + mailmanServer.post(mailNow); + testServer.processIncoming(); + testServer.resetCallCount(); + var conversations = mailmanList.conversations(duration2Months); + assertEquals(2, conversations.size()); + assertEquals(1, testServer.callCount()); + } + { + // Another mail from last month should be found + var mail1monthAgo2 = Email.create(sender, "Subject 1 month ago 2", "Body 2") + .recipient(EmailAddress.parse(listAddress)) + .date(now.minusMonths(1)) + .build(); + mailmanServer.post(mail1monthAgo2); + testServer.processIncoming(); + testServer.resetCallCount(); + var conversations = mailmanList.conversations(duration2Months); + assertEquals(3, conversations.size()); + assertEquals(1, testServer.callCount()); + } + { + // Another current mail should be found + var mailNow2 = Email.create(sender, "Subject now 2", "Body 3") + .recipient(EmailAddress.parse(listAddress)) + .build(); + mailmanServer.post(mailNow2); + testServer.processIncoming(); + testServer.resetCallCount(); + var conversations = mailmanList.conversations(duration2Months); + assertEquals(4, conversations.size()); + assertEquals(1, testServer.callCount()); + } + } + } +} diff --git a/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java b/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java index 193d0df52..7df30bc4d 100644 --- a/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java +++ b/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java @@ -23,7 +23,12 @@ package org.openjdk.skara.test; import com.sun.net.httpserver.*; +import java.nio.charset.Charset; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.util.zip.GZIPOutputStream; import org.openjdk.skara.email.*; import org.openjdk.skara.mailinglist.Mbox; import org.openjdk.skara.network.URIBuilder; @@ -46,6 +51,10 @@ public static TestMailmanServer createV2() throws IOException { return new TestMailman2Server(); } + public static TestMailmanServer createV3() throws IOException { + return new TestMailman3Server(); + } + private class Handler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { @@ -56,12 +65,11 @@ public void handle(HttpExchange exchange) throws IOException { exchange.close(); return; } - var response = mboxContents.toString(); lastResponseCached = false; try { var digest = MessageDigest.getInstance("SHA-256"); - digest.update(response.getBytes(StandardCharsets.UTF_8)); + digest.update(mboxContents); var etag = "\"" + Base64.getUrlEncoder().encodeToString(digest.digest()) + "\""; exchange.getResponseHeaders().add("ETag", etag); @@ -73,10 +81,9 @@ public void handle(HttpExchange exchange) throws IOException { } } - var responseBytes = response.getBytes(StandardCharsets.UTF_8); - exchange.sendResponseHeaders(200, responseBytes.length); + exchange.sendResponseHeaders(200, mboxContents.length); OutputStream outputStream = exchange.getResponseBody(); - outputStream.write(responseBytes); + outputStream.write(mboxContents); outputStream.close(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); @@ -94,7 +101,7 @@ protected TestMailmanServer() throws IOException { smtpServer = new SMTPServer(); } - protected abstract StringBuilder getMboxContents(HttpExchange exchange); + protected abstract byte[] getMboxContents(HttpExchange exchange); public URI getArchive() { return URIBuilder.base("http://" + httpServer.getAddress().getHostString() + ":" + httpServer.getAddress().getPort() + "/test/").build(); @@ -169,7 +176,7 @@ protected void archiveEmail(Email email, String mboxEntry) { } @Override - protected StringBuilder getMboxContents(HttpExchange exchange) { + protected byte[] getMboxContents(HttpExchange exchange) { var listMatcher = listPathPattern.matcher(exchange.getRequestURI().getPath()); if (!listMatcher.matches()) { throw new RuntimeException(); @@ -177,7 +184,12 @@ protected StringBuilder getMboxContents(HttpExchange exchange) { var listPath = listMatcher.group(1); var datePath = listMatcher.group(2); var listMap = lists.get(listPath); - return listMap.get(datePath); + var contents = listMap.get(datePath); + if (contents != null) { + return contents.toString().getBytes(StandardCharsets.UTF_8); + } else { + return null; + } } @Override @@ -187,3 +199,77 @@ public String createList(String name) { return listName; } } + +class TestMailman3Server extends TestMailmanServer { + + private record EmailEntry(Email email, String mbox) {} + + private Map> lists = new HashMap<>(); + + private static final Pattern listPathPattern = Pattern.compile("^/test/list/(.*?)/export/(.*)\\.mbox.gz"); + + protected TestMailman3Server() throws IOException { + super(); + } + + @Override + protected byte[] getMboxContents(HttpExchange exchange) { + // https://mail-dev.example.com/archives/list/skara-test@mail-dev.example.com/export/foo.mbox.gz?start=2024-10-25&end=2025-10-25 + var listMatcher = listPathPattern.matcher(exchange.getRequestURI().getPath()); + if (!listMatcher.matches()) { + throw new RuntimeException(); + } + var listPath = listMatcher.group(1); + + var query = exchange.getRequestURI().getRawQuery(); + String[] pairs = query.split("&"); + ZonedDateTime start = null; + ZonedDateTime end = null; + for (String pair : pairs) { + int i = pair.indexOf("="); + if (i > 0) { + String key = URLDecoder.decode(pair.substring(0, i), StandardCharsets.UTF_8); + String value = URLDecoder.decode(pair.substring(i + 1), StandardCharsets.UTF_8); + if ("start".equals(key)) { + start = LocalDate.parse(value).atStartOfDay(ZoneId.systemDefault()); + } else if ("end".equals(key)) { + end = LocalDate.parse(value).atStartOfDay(ZoneId.systemDefault()); + } + } else { + throw new RuntimeException(); + } + } + var entryList = lists.get(listPath); + var mbox = new StringBuilder(); + var startDate = start; + var endDate = end; + entryList.stream() + .filter(e -> startDate == null || startDate.isBefore(e.email.date())) + .filter(e -> endDate == null || endDate.isAfter(e.email.date())) + .forEach(e -> mbox.append(e.mbox)); + + var zipped = new ByteArrayOutputStream(); + try (var out = new OutputStreamWriter(new GZIPOutputStream(zipped))) { + out.write(mbox.toString()); + } catch (IOException e) { + throw new RuntimeException(e); + } + return zipped.toByteArray(); + } + + @Override + public String createList(String name) { + var emailAddress = EmailAddress.parse(name + "@" + httpServer.getAddress().getHostString()); + lists.put(emailAddress.address(), new ArrayList<>()); + return emailAddress.toString(); + } + + @Override + protected void archiveEmail(Email email, String mboxEntry) { + var entryList = email.recipients().stream() + .filter(recipient -> lists.containsKey(recipient.address())) + .map(recipient -> lists.get(recipient.address())) + .findAny().orElseThrow(); + entryList.add(new EmailEntry(email, mboxEntry)); + } +} From 6b40e21383d6e3b9116d031226aa49e224fe1ab7 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 29 Oct 2025 10:53:08 -0700 Subject: [PATCH 03/10] Bot factory support for different archive types --- .../skara/bots/mlbridge/ArchiveWorkItem.java | 3 +- .../mlbridge/MailingListArchiveReaderBot.java | 12 +- .../bots/mlbridge/MailingListBridgeBot.java | 31 +-- .../mlbridge/MailingListBridgeBotBuilder.java | 31 +-- .../mlbridge/MailingListBridgeBotFactory.java | 44 ++- .../MailingListArchiveReaderBotTests.java | 30 +-- .../MailingListBridgeBotFactoryTest.java | 41 ++- .../mlbridge/MailingListBridgeBotTests.java | 252 ++++++++++-------- .../mailman/MailmanListReader.java | 1 - .../mailinglist/mailman/MailmanServer.java | 7 +- 10 files changed, 249 insertions(+), 203 deletions(-) diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java index 60d9823f1..9af2dcd2f 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/ArchiveWorkItem.java @@ -378,7 +378,6 @@ public Collection run(Path scratchPath) { var jsonWebrevPath = scratchPath.resolve("mlbridge-webrevs").resolve("json"); var htmlWebrevPath = scratchPath.resolve("mlbridge-webrevs").resolve("html"); - var listServer = MailingListServerFactory.createMailman2Server(bot.listArchive(), bot.smtpServer(), bot.sendInterval()); var archiver = new ReviewArchive(pr, bot.emailAddress()); var lastDraftTime = pr.lastMarkedAsDraftTime().orElse(null); @@ -449,7 +448,7 @@ public Collection run(Path scratchPath) { .headers(bot.headers()) .recipients(recipients) .build(); - listServer.post(filteredEmail); + bot.mailingListServer().post(filteredEmail); } // Mixing forge time and local time for the latency is not ideal, but the best // we can do here. diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBot.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBot.java index 862c78f0f..0d7fac1bd 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBot.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBot.java @@ -35,7 +35,7 @@ import java.util.stream.Collectors; public class MailingListArchiveReaderBot implements Bot { - private final MailingListReader list; + private final MailingListReader mailingListReader; private final HostedRepository repository; private final Map parsedConversations = new HashMap<>(); private final Map resolvedPullRequests = new HashMap<>(); @@ -44,8 +44,8 @@ public class MailingListArchiveReaderBot implements Bot { private static final Pattern PULL_REQUEST_LINK_PATTERN = Pattern.compile("^(?:PR: |Pull request:\\R)(.*?)$", Pattern.MULTILINE); private final Logger log = Logger.getLogger("org.openjdk.skara.bots.mlbridge"); - MailingListArchiveReaderBot(MailingListReader list, HostedRepository repository) { - this.list = list; + MailingListArchiveReaderBot(MailingListReader mailingListReader, HostedRepository repository) { + this.mailingListReader = mailingListReader; this.repository = repository; } @@ -131,7 +131,7 @@ synchronized void inspect(Conversation conversation) { @Override public List getPeriodicItems() { - var readerItems = new ArchiveReaderWorkItem(this, list); + var readerItems = new ArchiveReaderWorkItem(this, mailingListReader); var ret = new ArrayList(); ret.add(readerItems); @@ -145,6 +145,10 @@ public List getPeriodicItems() { return ret; } + public MailingListReader mailingListReader() { + return mailingListReader; + } + @Override public String name() { return MailingListBridgeBotFactory.NAME; diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBot.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBot.java index 0fff80acc..c3747f7b4 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBot.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBot.java @@ -32,6 +32,7 @@ import java.util.*; import java.util.logging.Logger; import java.util.regex.Pattern; +import org.openjdk.skara.mailinglist.MailingListServer; public class MailingListBridgeBot implements Bot { private final EmailAddress emailAddress; @@ -43,19 +44,17 @@ public class MailingListBridgeBot implements Bot { private final List lists; private final Set ignoredUsers; private final Set ignoredComments; - private final URI listArchive; - private final String smtpServer; private final WebrevStorage webrevStorage; private final Set readyLabels; private final Map readyComments; private final Map headers; private final URI issueTracker; - private final Duration sendInterval; private final Duration cooldown; private final boolean repoInSubject; private final Pattern branchInSubject; private final Path seedStorage; private final PullRequestPoller poller; + private final MailingListServer mailingListServer; private final Logger log = Logger.getLogger("org.openjdk.skara.bots.mlbridge"); @@ -63,13 +62,13 @@ public class MailingListBridgeBot implements Bot { MailingListBridgeBot(EmailAddress from, HostedRepository repo, HostedRepository archive, String archiveRef, HostedRepository censusRepo, String censusRef, List lists, - Set ignoredUsers, Set ignoredComments, URI listArchive, String smtpServer, + Set ignoredUsers, Set ignoredComments, HostedRepository webrevStorageHTMLRepository, HostedRepository webrevStorageJSONRepository, String webrevStorageRef, Path webrevStorageBase, URI webrevStorageBaseUri, boolean webrevGenerateHTML, boolean webrevGenerateJSON, Set readyLabels, Map readyComments, URI issueTracker, Map headers, - Duration sendInterval, Duration cooldown, boolean repoInSubject, Pattern branchInSubject, - Path seedStorage) { + Duration cooldown, boolean repoInSubject, Pattern branchInSubject, + Path seedStorage, MailingListServer mailingListServer) { emailAddress = from; codeRepo = repo; archiveRepo = archive; @@ -79,17 +78,15 @@ public class MailingListBridgeBot implements Bot { this.lists = lists; this.ignoredUsers = ignoredUsers; this.ignoredComments = ignoredComments; - this.listArchive = listArchive; - this.smtpServer = smtpServer; this.readyLabels = readyLabels; this.readyComments = readyComments; this.headers = headers; this.issueTracker = issueTracker; - this.sendInterval = sendInterval; this.cooldown = cooldown; this.repoInSubject = repoInSubject; this.branchInSubject = branchInSubject; this.seedStorage = seedStorage; + this.mailingListServer = mailingListServer; webrevStorage = new WebrevStorage(webrevStorageHTMLRepository, webrevStorageJSONRepository, webrevStorageRef, webrevStorageBase, webrevStorageBaseUri, from, @@ -129,10 +126,6 @@ List lists() { return lists; } - Duration sendInterval() { - return sendInterval; - } - Duration cooldown() { return cooldown; } @@ -145,14 +138,6 @@ Set ignoredComments() { return ignoredComments; } - URI listArchive() { - return listArchive; - } - - String smtpServer() { - return smtpServer; - } - WebrevStorage webrevStorage() { return webrevStorage; } @@ -193,6 +178,10 @@ public void setLabelsUpdated(boolean labelsUpdated) { this.labelsUpdated = labelsUpdated; } + public MailingListServer mailingListServer() { + return mailingListServer; + } + @Override public List getPeriodicItems() { List ret = new LinkedList<>(); diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotBuilder.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotBuilder.java index 4226f8b9f..89679b250 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotBuilder.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotBuilder.java @@ -22,6 +22,7 @@ */ package org.openjdk.skara.bots.mlbridge; +import org.openjdk.skara.mailinglist.MailingListServer; import org.openjdk.skara.vcs.Branch; import org.openjdk.skara.vcs.VCS; import org.openjdk.skara.email.EmailAddress; @@ -43,8 +44,6 @@ public class MailingListBridgeBotBuilder { private List lists; private Set ignoredUsers = Set.of(); private Set ignoredComments = Set.of(); - private URI listArchive; - private String smtpServer; private HostedRepository webrevStorageHTMLRepository; private HostedRepository webrevStorageJSONRepository; private String webrevStorageRef; @@ -56,11 +55,11 @@ public class MailingListBridgeBotBuilder { private Map readyComments = Map.of(); private URI issueTracker; private Map headers = Map.of(); - private Duration sendInterval = Duration.ZERO; private Duration cooldown = Duration.ZERO; private boolean repoInSubject = false; private Pattern branchInSubject = Pattern.compile("a^"); // Does not match anything private Path seedStorage = null; + private MailingListServer mailingListServer; MailingListBridgeBotBuilder() { } @@ -110,16 +109,6 @@ public MailingListBridgeBotBuilder ignoredComments(Set ignoredComments) return this; } - public MailingListBridgeBotBuilder listArchive(URI listArchive) { - this.listArchive = listArchive; - return this; - } - - public MailingListBridgeBotBuilder smtpServer(String smtpServer) { - this.smtpServer = smtpServer; - return this; - } - public MailingListBridgeBotBuilder webrevStorageHTMLRepository(HostedRepository webrevStorageHTMLRepository) { this.webrevStorageHTMLRepository = webrevStorageHTMLRepository; return this; @@ -175,11 +164,6 @@ public MailingListBridgeBotBuilder headers(Map headers) { return this; } - public MailingListBridgeBotBuilder sendInterval(Duration sendInterval) { - this.sendInterval = sendInterval; - return this; - } - public MailingListBridgeBotBuilder cooldown(Duration cooldown) { this.cooldown = cooldown; return this; @@ -200,12 +184,17 @@ public MailingListBridgeBotBuilder seedStorage(Path seedStorage) { return this; } + public MailingListBridgeBotBuilder mailingListServer(MailingListServer mailingListServer) { + this.mailingListServer = mailingListServer; + return this; + } + public MailingListBridgeBot build() { return new MailingListBridgeBot(from, repo, archive, archiveRef, censusRepo, censusRef, lists, - ignoredUsers, ignoredComments, listArchive, smtpServer, + ignoredUsers, ignoredComments, webrevStorageHTMLRepository, webrevStorageJSONRepository, webrevStorageRef, webrevStorageBase, webrevStorageBaseUri, webrevGenerateHTML, webrevGenerateJSON, - readyLabels, readyComments, issueTracker, headers, sendInterval, - cooldown, repoInSubject, branchInSubject, seedStorage); + readyLabels, readyComments, issueTracker, headers, + cooldown, repoInSubject, branchInSubject, seedStorage, mailingListServer); } } diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java index 6b424bd5a..da3629976 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java @@ -22,9 +22,11 @@ */ package org.openjdk.skara.bots.mlbridge; +import java.net.URI; import org.openjdk.skara.bot.*; import org.openjdk.skara.email.EmailAddress; import org.openjdk.skara.mailinglist.MailingListReader; +import org.openjdk.skara.mailinglist.MailingListServer; import org.openjdk.skara.network.URIBuilder; import org.openjdk.skara.json.*; import org.openjdk.skara.mailinglist.MailingListServerFactory; @@ -77,6 +79,10 @@ public List create(BotConfiguration configuration) { .map(pattern -> Pattern.compile(pattern, Pattern.MULTILINE | Pattern.DOTALL)) .collect(Collectors.toSet()); var listArchive = URIBuilder.base(specific.get("server").get("archive").asString()).build(); + String archiveType = null; + if (specific.get("server").contains("type")) { + archiveType = specific.get("server").get("type").asString(); + } var listSmtp = specific.get("server").get("smtp").asString(); var interval = specific.get("server").contains("interval") ? Duration.parse(specific.get("server").get("interval").asString()) : Duration.ofSeconds(1); @@ -101,7 +107,7 @@ public List create(BotConfiguration configuration) { if (specific.get("server").contains("etag")) { useEtag = specific.get("server").get("etag").asBoolean(); } - var mailmanServer = MailingListServerFactory.createMailman2Server(listArchive, listSmtp, Duration.ZERO, useEtag); + MailingListServer mailmanServer = createMailmanServer(archiveType, listArchive, listSmtp, useEtag); var mailingListReaderMap = new HashMap, MailingListReader>(); @@ -121,6 +127,22 @@ public List create(BotConfiguration configuration) { .collect(Collectors.toMap(JSONObject.Field::name, field -> field.value().asString())) : Map.of(); + // Allow overriding the archive pre repository + URI repoListArchive = null; + if (repoConfig.contains("server") && repoConfig.get("server").contains("archive")) { + repoListArchive = URIBuilder.base(repoConfig.get("server").get("archive").asString()).build(); + } + MailingListServer repoMailmanServer; + if (repoListArchive != null) { + String repoArchiveType = archiveType; + if (repoConfig.get("server").contains("type")) { + repoArchiveType = repoConfig.get("server").get("type").asString(); + } + repoMailmanServer = createMailmanServer(repoArchiveType, repoListArchive, listSmtp, useEtag); + } else { + repoMailmanServer = mailmanServer; + } + var lists = parseLists(repoConfig.get("lists")); if (!repoConfig.contains("bidirectional") || repoConfig.get("bidirectional").asBoolean()) { var listNamesForReading = new HashSet(); @@ -134,7 +156,7 @@ public List create(BotConfiguration configuration) { // Reuse MailingListReaders with the exact same set of mailing lists between bots // to benefit more from cached results. if (!mailingListReaderMap.containsKey(listsForReading)) { - mailingListReaderMap.put(listsForReading, mailmanServer.getListReader(listsForReading.toArray(new String[0]))); + mailingListReaderMap.put(listsForReading, repoMailmanServer.getListReader(listsForReading.toArray(new String[0]))); } var bot = new MailingListArchiveReaderBot(mailingListReaderMap.get(listsForReading), hostedRepository); ret.add(bot); @@ -161,8 +183,6 @@ public List create(BotConfiguration configuration) { .lists(lists) .ignoredUsers(ignoredUsers) .ignoredComments(ignoredComments) - .listArchive(listArchive) - .smtpServer(listSmtp) .webrevStorageHTMLRepository(webrevHTMLRepo) .webrevStorageJSONRepository(webrevJSONRepo) .webrevStorageRef(webrevRef) @@ -174,9 +194,9 @@ public List create(BotConfiguration configuration) { .readyComments(readyComments) .issueTracker(issueTracker) .headers(headers) - .sendInterval(interval) .cooldown(cooldown) - .seedStorage(configuration.storageFolder().resolve("seeds")); + .seedStorage(configuration.storageFolder().resolve("seeds")) + .mailingListServer(repoMailmanServer); if (repoConfig.contains("reponame")) { botBuilder.repoInSubject(repoConfig.get("reponame").asBoolean()); @@ -189,4 +209,16 @@ public List create(BotConfiguration configuration) { return ret; } + + private static MailingListServer createMailmanServer(String archiveType, URI listArchive, String listSmtp, boolean useEtag) { + MailingListServer mailmanServer; + if (archiveType == null || archiveType.equals("mailman2")) { + mailmanServer = MailingListServerFactory.createMailman2Server(listArchive, listSmtp, Duration.ZERO, useEtag); + } else if (archiveType.equals("mailman3")) { + mailmanServer = MailingListServerFactory.createMailman3Server(listArchive, listSmtp, Duration.ZERO, useEtag); + } else { + throw new RuntimeException("Invalid server archive type: " + archiveType); + } + return mailmanServer; + } } diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java index f465c2009..273eae262 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListArchiveReaderBotTests.java @@ -68,6 +68,8 @@ void simpleArchive(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -75,18 +77,14 @@ void simpleArchive(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); - // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), - Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var readerBot = new MailingListArchiveReaderBot(mailmanList, archive); @@ -143,6 +141,8 @@ void rememberBridged(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -150,19 +150,15 @@ void rememberBridged(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .repoInSubject(true) + .mailingListServer(mailmanServer) .build(); - // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), - Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var readerBot = new MailingListArchiveReaderBot(mailmanList, archive); @@ -220,6 +216,9 @@ void largeEmail(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + // The mailing list as well + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -227,18 +226,14 @@ void largeEmail(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); - // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), - Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var readerBot = new MailingListArchiveReaderBot(mailmanList, archive); @@ -302,6 +297,8 @@ void branchMissing(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -309,13 +306,12 @@ void branchMissing(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java index 0b7f4ddc1..ce92956b4 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java @@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test; import org.openjdk.skara.bot.Bot; import org.openjdk.skara.json.JWCC; +import org.openjdk.skara.mailinglist.MailingListReader; +import org.openjdk.skara.mailinglist.MailingListServer; import org.openjdk.skara.test.TemporaryDirectory; import org.openjdk.skara.test.TestBotFactory; import org.openjdk.skara.test.TestHost; @@ -135,7 +137,11 @@ public void testCreate() { ] } ], - "issues": "https://test.test.com/issueProject" + "issues": "https://test.test.com/issueProject", + "server": { + "archive": "https://test.example.com/archive", + "type": "mailman3" + } } ] } @@ -165,72 +171,79 @@ public void testCreate() { assertEquals(2, mailingListArchiveReaderBots.size()); assertEquals(3, mailingListBridgeBots.size()); - assertEquals("MailingListArchiveReaderBot@repo3", mailingListArchiveReaderBots.get(0).toString()); - assertEquals("MailingListArchiveReaderBot@repo5", mailingListArchiveReaderBots.get(1).toString()); + MailingListArchiveReaderBot mailingListArchiveReaderBot1 = + (MailingListArchiveReaderBot) mailingListArchiveReaderBots.get(0); + assertEquals("MailingListArchiveReaderBot@repo3", mailingListArchiveReaderBot1.toString()); + MailingListReader readerBot1MailingListReader = mailingListArchiveReaderBot1.mailingListReader(); + assertTrue(readerBot1MailingListReader.getClass().getName().contains("Mailman2"), + readerBot1MailingListReader.getClass().getName()); + + MailingListArchiveReaderBot mailingListArchiveReaderBot2 = + (MailingListArchiveReaderBot) mailingListArchiveReaderBots.get(1); + assertEquals("MailingListArchiveReaderBot@repo5", mailingListArchiveReaderBot2.toString()); + MailingListReader readerBot2MailingListReader = mailingListArchiveReaderBot2.mailingListReader(); + assertTrue(readerBot2MailingListReader.getClass().getName().contains("Mailman3"), + readerBot2MailingListReader.getClass().getName()); MailingListBridgeBot mailingListBridgeBot1 = (MailingListBridgeBot) mailingListBridgeBots.get(0); assertEquals("MailingListBridgeBot@repo3", mailingListBridgeBot1.toString()); assertEquals("repo3", mailingListBridgeBot1.codeRepo().name()); assertEquals("archive", mailingListBridgeBot1.archiveRepo().name()); assertEquals("master", mailingListBridgeBot1.archiveRef()); - assertEquals("https://mail.test.org/test/", mailingListBridgeBot1.listArchive().toString()); assertEquals("master", mailingListBridgeBot1.censusRef()); assertEquals("census", mailingListBridgeBot1.censusRepo().name()); assertEquals("", mailingListBridgeBot1.lists().get(0).list().toString()); assertEquals("[ignore1[bot], ignore2[bot], ignore4[bot], ignore3[bot]]", mailingListBridgeBot1.ignoredUsers().toString()); assertEquals("[]", mailingListBridgeBot1.ignoredComments().toString()); - assertEquals("0.0.0.0", mailingListBridgeBot1.smtpServer()); assertEquals("[rfr]", mailingListBridgeBot1.readyLabels().toString()); assertEquals("{test_user[bot]=}", mailingListBridgeBot1.readyComments().toString()); assertEquals("{Approved=test}", mailingListBridgeBot1.headers().toString()); assertEquals("https://bugs.test.org/browse/", mailingListBridgeBot1.issueTracker().toString()); - assertEquals(Duration.ofSeconds(5), mailingListBridgeBot1.sendInterval()); assertEquals(Duration.ofMinutes(2), mailingListBridgeBot1.cooldown()); assertFalse(mailingListBridgeBot1.repoInSubject()); assertEquals("dev", mailingListBridgeBot1.branchInSubject().toString()); - + MailingListServer bridgeBot1MailingListServer = mailingListBridgeBot1.mailingListServer(); + assertTrue(bridgeBot1MailingListServer.getClass().getName().contains("Mailman2")); MailingListBridgeBot mailingListBridgeBot2 = (MailingListBridgeBot) mailingListBridgeBots.get(1); assertEquals("MailingListBridgeBot@repo4", mailingListBridgeBot2.toString()); assertEquals("repo4", mailingListBridgeBot2.codeRepo().name()); assertEquals("archive", mailingListBridgeBot2.archiveRepo().name()); assertEquals("master", mailingListBridgeBot2.archiveRef()); - assertEquals("https://mail.test.org/test/", mailingListBridgeBot2.listArchive().toString()); assertEquals("master", mailingListBridgeBot2.censusRef()); assertEquals("census", mailingListBridgeBot2.censusRepo().name()); assertEquals("", mailingListBridgeBot2.lists().get(0).list().toString()); assertEquals("[ignore1[bot], ignore2[bot], ignore4[bot], ignore3[bot]]", mailingListBridgeBot2.ignoredUsers().toString()); assertEquals("[]", mailingListBridgeBot2.ignoredComments().toString()); - assertEquals("0.0.0.0", mailingListBridgeBot2.smtpServer()); assertEquals("[rfr]", mailingListBridgeBot2.readyLabels().toString()); assertEquals("{test_user[bot]=}", mailingListBridgeBot2.readyComments().toString()); assertEquals(0, mailingListBridgeBot2.headers().size()); assertEquals("https://bugs.test.org/browse/", mailingListBridgeBot2.issueTracker().toString()); - assertEquals(Duration.ofSeconds(5), mailingListBridgeBot2.sendInterval()); assertEquals(Duration.ofMinutes(2), mailingListBridgeBot2.cooldown()); assertTrue(mailingListBridgeBot2.repoInSubject()); + MailingListServer bridgeBot2MailingListServer = mailingListBridgeBot2.mailingListServer(); + assertTrue(bridgeBot2MailingListServer.getClass().getName().contains("Mailman2")); MailingListBridgeBot mailingListBridgeBot3 = (MailingListBridgeBot) mailingListBridgeBots.get(2); assertEquals("MailingListBridgeBot@repo5", mailingListBridgeBot3.toString()); assertEquals("repo5", mailingListBridgeBot3.codeRepo().name()); assertEquals("archive", mailingListBridgeBot3.archiveRepo().name()); assertEquals("master", mailingListBridgeBot3.archiveRef()); - assertEquals("https://mail.test.org/test/", mailingListBridgeBot3.listArchive().toString()); assertEquals("master", mailingListBridgeBot3.censusRef()); assertEquals("census", mailingListBridgeBot3.censusRepo().name()); assertEquals("", mailingListBridgeBot3.lists().get(0).list().toString()); assertEquals("[label1, label2, label3]", mailingListBridgeBot3.lists().get(0).labels().toString()); assertEquals("[ignore1[bot], ignore2[bot], ignore4[bot], ignore3[bot]]", mailingListBridgeBot3.ignoredUsers().toString()); assertEquals("[]", mailingListBridgeBot3.ignoredComments().toString()); - assertEquals("0.0.0.0", mailingListBridgeBot3.smtpServer()); assertEquals("[rfr]", mailingListBridgeBot3.readyLabels().toString()); assertEquals("{test_user[bot]=}", mailingListBridgeBot3.readyComments().toString()); assertEquals("{Approved=test5}", mailingListBridgeBot3.headers().toString()); assertEquals("https://test.test.com/issueProject", mailingListBridgeBot3.issueTracker().toString()); - assertEquals(Duration.ofSeconds(5), mailingListBridgeBot3.sendInterval()); assertEquals(Duration.ofMinutes(2), mailingListBridgeBot3.cooldown()); assertTrue(mailingListBridgeBot3.repoInSubject()); assertEquals("master", mailingListBridgeBot3.branchInSubject().toString()); + MailingListServer bridgeBot3MailingListServer = mailingListBridgeBot3.mailingListServer(); + assertTrue(bridgeBot3MailingListServer.getClass().getName().contains("Mailman3")); } } -} \ No newline at end of file +} diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java index f6bdedfd5..7668aba27 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java @@ -120,6 +120,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -128,8 +129,7 @@ void simpleArchive(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of()) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) + .mailingListServer(mailmanServer) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -138,7 +138,6 @@ void simpleArchive(TestInfo testInfo) throws IOException { .readyComments(Map.of(ignored.forge().currentUser().username(), Pattern.compile("ready"))) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .headers(Map.of("Extra1", "val1", "Extra2", "val2")) - .sendInterval(Duration.ZERO) .build(); // Populate the projects repository @@ -230,7 +229,6 @@ void simpleArchive(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -316,6 +314,8 @@ void archiveIntegrated(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -323,13 +323,12 @@ void archiveIntegrated(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -409,6 +408,8 @@ void archiveLegacyIntegrated(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -416,13 +417,12 @@ void archiveLegacyIntegrated(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -483,6 +483,8 @@ void archiveDirectToIntegrated(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -490,13 +492,12 @@ void archiveDirectToIntegrated(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -562,6 +563,8 @@ void archiveIntegratedRetainPrefix(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -569,14 +572,13 @@ void archiveIntegratedRetainPrefix(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .readyLabels(Set.of("rfr")) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -639,6 +641,8 @@ void archiveClosed(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -646,14 +650,13 @@ void archiveClosed(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .readyLabels(Set.of("rfr")) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -728,6 +731,8 @@ void archiveFailedAutoMerge(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -735,13 +740,12 @@ void archiveFailedAutoMerge(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -782,6 +786,8 @@ void reviewComment(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -789,13 +795,12 @@ void reviewComment(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -835,7 +840,6 @@ void reviewComment(TestInfo testInfo) throws IOException { assertFalse(archiveContains(archiveFolder.path(), "Don't mind me")); // The mailing list as well - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -890,19 +894,20 @@ void combineComments(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -936,7 +941,6 @@ void combineComments(TestInfo testInfo) throws IOException { assertEquals(2, archiveContainsCount(archiveFolder.path(), "^On.*wrote:")); // As well as the mailing list - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -989,19 +993,20 @@ void commentThreading(TestInfo testInfo) throws IOException { .addReviewer(reviewer.forge().currentUser().id()) .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1057,7 +1062,6 @@ void commentThreading(TestInfo testInfo) throws IOException { assertTrue(archiveText.indexOf("Looks fine") < archiveText.indexOf("The final review comment")); // Check the mailing list - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1118,19 +1122,20 @@ void commentThreadingSeparated(TestInfo testInfo) throws IOException { .addReviewer(reviewer.forge().currentUser().id()) .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1190,19 +1195,20 @@ void commentWithMention(TestInfo testInfo) throws IOException { .addReviewer(reviewer.forge().currentUser().id()) .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1254,19 +1260,20 @@ void reviewCommentWithMention(TestInfo testInfo) throws IOException { .addReviewer(reviewer.forge().currentUser().id()) .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1319,19 +1326,20 @@ void commentWithQuote(TestInfo testInfo) throws IOException { .addReviewer(reviewer.forge().currentUser().id()) .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1382,19 +1390,20 @@ void reviewContext(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1438,19 +1447,20 @@ void multipleReviewContexts(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1514,19 +1524,20 @@ void filterComments(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1604,19 +1615,20 @@ void incrementalChanges(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1667,7 +1679,6 @@ void incrementalChanges(TestInfo testInfo) throws IOException { assertEquals(1, webrevComments.size()); // Check that sender address is set properly - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1715,19 +1726,20 @@ void forcePushed(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var sender = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(sender) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1775,7 +1787,6 @@ void forcePushed(TestInfo testInfo) throws IOException { assertEquals(1, webrevComments.size()); // Check that sender address is set properly - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1802,19 +1813,20 @@ void rebased(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var sender = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(sender) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1869,7 +1881,6 @@ void rebased(TestInfo testInfo) throws IOException { assertEquals(1, webrevComments.size()); // Check that sender address is set properly - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -1895,6 +1906,8 @@ void incrementalAfterRebase(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var sender = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(sender) .repo(author) @@ -1902,13 +1915,12 @@ void incrementalAfterRebase(TestInfo testInfo) throws IOException { .archiveRef("archive") .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -1975,6 +1987,8 @@ void mergeWebrev(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -1982,13 +1996,12 @@ void mergeWebrev(TestInfo testInfo) throws IOException { .archiveRef("archive") .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2061,6 +2074,8 @@ void mergeWebrevConflict(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -2068,13 +2083,12 @@ void mergeWebrevConflict(TestInfo testInfo) throws IOException { .archiveRef("archive") .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2133,6 +2147,8 @@ void mergeWebrevNoConflict(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -2140,13 +2156,12 @@ void mergeWebrevNoConflict(TestInfo testInfo) throws IOException { .archiveRef("archive") .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2204,6 +2219,8 @@ void skipAddingExistingWebrev(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -2211,13 +2228,12 @@ void skipAddingExistingWebrev(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2285,19 +2301,20 @@ void notifyReviewVerdicts(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addReviewer(reviewer.forge().currentUser().id()) .addAuthor(author.forge().currentUser().id()); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2344,7 +2361,6 @@ void notifyReviewVerdicts(TestInfo testInfo) throws IOException { listServer.processIncoming(); listServer.processIncoming(); listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertTrue(conversations.get(0).allMessages().get(1).body().contains("hosted.git/pr/1/review/0")); @@ -2377,6 +2393,8 @@ void ignoreComments(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -2385,13 +2403,12 @@ void ignoreComments(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of(Pattern.compile("ignore this comment", Pattern.MULTILINE | Pattern.DOTALL))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2444,19 +2461,20 @@ void replyToEmptyReview(TestInfo testInfo) throws IOException { .addReviewer(reviewer.forge().currentUser().id()) .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2504,6 +2522,8 @@ void cooldown(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBotBuilder = MailingListBridgeBot.newBuilder() .from(from) .repo(bot) @@ -2511,13 +2531,12 @@ void cooldown(TestInfo testInfo) throws IOException { .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) - .issueTracker(URIBuilder.base("http://issues.test/browse/").build()); + .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer); // Populate the projects repository var reviewFile = Path.of("reviewfile.txt"); @@ -2569,6 +2588,8 @@ void cooldownNewRevision(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBotBuilder = MailingListBridgeBot.newBuilder() .from(from) .repo(bot) @@ -2576,13 +2597,12 @@ void cooldownNewRevision(TestInfo testInfo) throws IOException { .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) - .issueTracker(URIBuilder.base("http://issues.test/browse/").build()); + .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer); // Populate the projects repository var reviewFile = Path.of("reviewfile.txt"); @@ -2636,6 +2656,8 @@ void retryAfterCooldown(TestInfo testInfo) throws IOException, InterruptedExcept .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); var cooldown = Duration.ofMillis(500); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBotBuilder = MailingListBridgeBot.newBuilder() .from(from) .repo(bot) @@ -2643,13 +2665,12 @@ void retryAfterCooldown(TestInfo testInfo) throws IOException, InterruptedExcept .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) - .issueTracker(URIBuilder.base("http://issues.test/browse/").build()); + .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer); // Populate the projects repository var reviewFile = Path.of("reviewfile.txt"); @@ -2726,20 +2747,21 @@ void branchPrefix(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .branchInSubject(Pattern.compile(".*")) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2783,20 +2805,21 @@ void repoPrefix(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .repoInSubject(true) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2840,14 +2863,14 @@ void repoAndBranchPrefix(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -2855,6 +2878,7 @@ void repoAndBranchPrefix(TestInfo testInfo) throws IOException { .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .repoInSubject(true) .branchInSubject(Pattern.compile(".*")) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -2900,6 +2924,8 @@ void retryNewRevisionAfterCooldown(TestInfo testInfo) throws IOException, Interr .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); var cooldown = Duration.ofMillis(500); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBotBuilder = MailingListBridgeBot.newBuilder() .from(from) .repo(bot) @@ -2907,13 +2933,12 @@ void retryNewRevisionAfterCooldown(TestInfo testInfo) throws IOException, Interr .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) - .issueTracker(URIBuilder.base("http://issues.test/browse/").build()); + .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer); // Populate the projects repository var reviewFile = Path.of("reviewfile.txt"); @@ -2992,6 +3017,8 @@ void multipleRecipients(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -2999,13 +3026,12 @@ void multipleRecipients(TestInfo testInfo) throws IOException { .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress1, Set.of("list1")), new MailingListConfiguration(listAddress2, Set.of("list2")))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3027,7 +3053,6 @@ void multipleRecipients(TestInfo testInfo) throws IOException { listServer.processIncoming(); // The mail should have been sent to list1 - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress1.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -3071,6 +3096,8 @@ void jsonArchive(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -3079,8 +3106,6 @@ void jsonArchive(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of()) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageJSONRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -3091,7 +3116,7 @@ void jsonArchive(TestInfo testInfo) throws IOException { .readyComments(Map.of(ignored.forge().currentUser().username(), Pattern.compile("ready"))) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .headers(Map.of("Extra1", "val1", "Extra2", "val2")) - .sendInterval(Duration.ZERO) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3159,7 +3184,6 @@ void jsonArchive(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -3272,6 +3296,8 @@ void rebaseOnRetry(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -3280,8 +3306,6 @@ void rebaseOnRetry(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of()) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -3289,7 +3313,7 @@ void rebaseOnRetry(TestInfo testInfo) throws IOException { .readyLabels(Set.of("rfr")) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .headers(Map.of("Extra1", "val1", "Extra2", "val2")) - .sendInterval(Duration.ZERO) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3359,19 +3383,20 @@ void dependent(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3432,19 +3457,20 @@ void commentWithQuoteFromBridged(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) .archive(archive) .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) .webrevStorageBaseUri(webrevServer.uri()) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3508,6 +3534,8 @@ void notArchiveDraftPR(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -3516,8 +3544,6 @@ void notArchiveDraftPR(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of()) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -3526,7 +3552,7 @@ void notArchiveDraftPR(TestInfo testInfo) throws IOException { .readyComments(Map.of(ignored.forge().currentUser().username(), Pattern.compile("ready"))) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .headers(Map.of("Extra1", "val1", "Extra2", "val2")) - .sendInterval(Duration.ZERO) + .mailingListServer(mailmanServer) .build(); // Populate the repository. @@ -3685,6 +3711,8 @@ void noWebrev(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -3693,8 +3721,6 @@ void noWebrev(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of()) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -3705,7 +3731,7 @@ void noWebrev(TestInfo testInfo) throws IOException { .readyComments(Map.of(ignored.forge().currentUser().username(), Pattern.compile("ready"))) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .headers(Map.of("Extra1", "val1", "Extra2", "val2")) - .sendInterval(Duration.ZERO) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3771,7 +3797,6 @@ void noWebrev(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -3831,6 +3856,8 @@ void mergeWithoutWebrev(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -3838,8 +3865,6 @@ void mergeWithoutWebrev(TestInfo testInfo) throws IOException { .archiveRef("archive") .censusRepo(censusBuilder.build()) .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -3847,6 +3872,7 @@ void mergeWithoutWebrev(TestInfo testInfo) throws IOException { .webrevGenerateJSON(false) .webrevGenerateHTML(false) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3917,6 +3943,8 @@ void archiveLongBody(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -3925,8 +3953,6 @@ void archiveLongBody(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of()) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -3935,7 +3961,7 @@ void archiveLongBody(TestInfo testInfo) throws IOException { .readyComments(Map.of(ignored.forge().currentUser().username(), Pattern.compile("ready"))) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .headers(Map.of("Extra1", "val1", "Extra2", "val2")) - .sendInterval(Duration.ZERO) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -3980,7 +4006,6 @@ void archiveLongBody(TestInfo testInfo) throws IOException { // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); @@ -4011,6 +4036,8 @@ void largeDiffArchive(TestInfo testInfo) throws IOException { var censusBuilder = credentials.getCensusBuilder() .addAuthor(author.forge().currentUser().id()); var from = EmailAddress.from("test", "test@test.mail"); + var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), + listServer.getSMTP(), Duration.ZERO); var mlBot = MailingListBridgeBot.newBuilder() .from(from) .repo(author) @@ -4019,8 +4046,6 @@ void largeDiffArchive(TestInfo testInfo) throws IOException { .lists(List.of(new MailingListConfiguration(listAddress, Set.of()))) .ignoredUsers(Set.of(ignored.forge().currentUser().username())) .ignoredComments(Set.of()) - .listArchive(listServer.getArchive()) - .smtpServer(listServer.getSMTP()) .webrevStorageHTMLRepository(archive) .webrevStorageRef("webrev") .webrevStorageBase(Path.of("test")) @@ -4029,7 +4054,7 @@ void largeDiffArchive(TestInfo testInfo) throws IOException { .readyComments(Map.of(ignored.forge().currentUser().username(), Pattern.compile("ready"))) .issueTracker(URIBuilder.base("http://issues.test/browse/").build()) .headers(Map.of("Extra1", "val1", "Extra2", "val2")) - .sendInterval(Duration.ZERO) + .mailingListServer(mailmanServer) .build(); // Populate the projects repository @@ -4063,7 +4088,6 @@ void largeDiffArchive(TestInfo testInfo) throws IOException { assertTrue(pr.store().comments().get(1).body().contains("[Full](Webrev is not available because diff is too large)")); // The mailing list as well listServer.processIncoming(); - var mailmanServer = MailingListServerFactory.createMailman3Server(listServer.getArchive(), listServer.getSMTP(), Duration.ZERO); var mailmanList = mailmanServer.getListReader(listAddress.address()); var conversations = mailmanList.conversations(Duration.ofDays(1)); assertEquals(1, conversations.size()); diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java index d8402a449..4b8eabc65 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java @@ -25,7 +25,6 @@ import java.nio.charset.StandardCharsets; import java.time.format.DateTimeFormatter; import java.util.zip.GZIPInputStream; -import java.util.zip.Inflater; import org.openjdk.skara.email.*; import org.openjdk.skara.mailinglist.*; diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java index 7b85a2cce..85bcdf335 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanServer.java @@ -24,13 +24,10 @@ import org.openjdk.skara.email.*; import org.openjdk.skara.mailinglist.*; -import org.openjdk.skara.network.URIBuilder; import java.io.*; import java.net.URI; import java.time.*; -import java.time.format.DateTimeFormatter; -import java.util.*; public abstract class MailmanServer implements MailingListServer { protected final URI archive; @@ -66,4 +63,8 @@ void sendMessage(Email message) { public void post(Email email) { sendMessage(email); } + + public URI archive() { + return archive; + } } From 0d89dff281fdddec3728d381d728c6ad8beb69f0 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 29 Oct 2025 12:26:30 -0700 Subject: [PATCH 04/10] MailingListNotifier config does not need archive --- .../MailingListNotifierFactory.java | 5 +++-- .../mailinglist/MailingListServerFactory.java | 5 +++++ .../mailinglist/mailman/SendOnlyServer.java | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java index 849291c3f..c7bc22eb8 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java @@ -22,10 +22,12 @@ */ package org.openjdk.skara.bots.notify.mailinglist; +import java.util.Optional; import org.openjdk.skara.bot.BotConfiguration; import org.openjdk.skara.bots.notify.*; import org.openjdk.skara.email.EmailAddress; import org.openjdk.skara.json.JSONObject; +import org.openjdk.skara.mailinglist.MailingListServer; import org.openjdk.skara.mailinglist.MailingListServerFactory; import org.openjdk.skara.network.URIBuilder; @@ -43,9 +45,8 @@ public String name() { public Notifier create(BotConfiguration botConfiguration, JSONObject notifierConfiguration) { var smtp = notifierConfiguration.get("smtp").asString(); var sender = EmailAddress.parse(notifierConfiguration.get("sender").asString()); - var archive = URIBuilder.base(notifierConfiguration.get("archive").asString()).build(); var interval = notifierConfiguration.contains("interval") ? Duration.parse(notifierConfiguration.get("interval").asString()) : Duration.ofSeconds(1); - var listServer = MailingListServerFactory.createMailman2Server(archive, smtp, interval); + var listServer = MailingListServerFactory.createSendOnlyServer(smtp, interval); var recipient = notifierConfiguration.get("recipient").asString(); var recipientAddress = EmailAddress.parse(recipient); diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java index 3f29f0aa0..ef819efa9 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java @@ -24,6 +24,7 @@ import org.openjdk.skara.mailinglist.mailman.Mailman2Server; import org.openjdk.skara.mailinglist.mailman.Mailman3Server; +import org.openjdk.skara.mailinglist.mailman.SendOnlyServer; import org.openjdk.skara.mailinglist.mboxfile.MboxFileListServer; import java.net.URI; @@ -47,6 +48,10 @@ public static MailingListServer createMailman3Server(URI archive, String smtp, D return new Mailman3Server(archive, smtp, sendInterval, useEtag); } + public static MailingListServer createSendOnlyServer(String smtp, Duration sendInterval) { + return new SendOnlyServer(smtp, sendInterval); + } + public static MailingListServer createMboxFileServer(Path file) { return new MboxFileListServer(file); } diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java new file mode 100644 index 000000000..82659a924 --- /dev/null +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java @@ -0,0 +1,18 @@ +package org.openjdk.skara.mailinglist.mailman; + +import java.time.Duration; +import org.openjdk.skara.mailinglist.MailingListReader; + +/** + * MailingListServer implementation that only implements the send message API. + */ +public class SendOnlyServer extends MailmanServer { + public SendOnlyServer(String smtpServer, Duration sendInterval) { + super(null, smtpServer, sendInterval, false); + } + + @Override + public MailingListReader getListReader(String... listNames) { + throw new UnsupportedOperationException(); + } +} From 1b1525b5d5e31ba6bec887b356ea2151c23292dd Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 21 Nov 2025 07:06:18 -0800 Subject: [PATCH 05/10] Parse new mbox format --- .../java/org/openjdk/skara/email/Email.java | 41 ++++++- .../org/openjdk/skara/email/EmailTests.java | 104 +++++++++++------- 2 files changed, 107 insertions(+), 38 deletions(-) diff --git a/email/src/main/java/org/openjdk/skara/email/Email.java b/email/src/main/java/org/openjdk/skara/email/Email.java index 9e3946ed9..6f8dbe15e 100644 --- a/email/src/main/java/org/openjdk/skara/email/Email.java +++ b/email/src/main/java/org/openjdk/skara/email/Email.java @@ -26,6 +26,8 @@ import java.time.format.*; import java.time.temporal.ChronoUnit; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -43,6 +45,8 @@ public class Email { "(\\r\\n){2}|(\\n){2}", Pattern.MULTILINE); private final static Pattern mboxMessageHeaderPattern = Pattern.compile( "^([-\\w]+): ((?:.(?!\\R\\w))*.)", Pattern.MULTILINE | Pattern.DOTALL); + private final static Pattern mboxMessageBodyHeaders = Pattern.compile( + "^(Content-Type|Content-Transfer-Encoding): .*"); Email(EmailAddress id, ZonedDateTime date, List recipients, EmailAddress author, EmailAddress sender, String subject, String body, Map headers) { this.id = id; @@ -71,10 +75,45 @@ private static MboxMessage parseMboxMessage(String message) { .replaceAll("\\R", ""))); ret.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); ret.headers.putAll(headers); - ret.body = parts[1].stripTrailing(); + + var boundary = parseBoundary(ret.headers); + if (boundary != null) { + // Content-Type: multipart/mixed; boundary="===============3685582790409215631==" + // + // --===============3685582790409215631== + // Content-Type: text/plain; charset="utf-8" + // Content-Transfer-Encoding: 7bit + // + // The body + // + // --===============3685582790409215631== + var firstEmptyLineRemoved = new AtomicBoolean(false); + ret.body = parts[1].lines() + .dropWhile(s -> !s.equals(boundary)) + .skip(1) + .dropWhile(s -> mboxMessageBodyHeaders.matcher(s).matches()) + .filter(s -> !(s.isEmpty() && !firstEmptyLineRemoved.getAndSet(true))) + .takeWhile(s -> !s.equals(boundary)) + .collect(Collectors.joining("\n")).stripTrailing(); + } else { + ret.body = parts[1].stripTrailing(); + } return ret; } + private final static Pattern mboxBoundaryPattern = Pattern.compile(".*boundary=\"([^\"]*)\".*"); + + private static String parseBoundary(Map headers) { + if (headers.containsKey("Content-Type")) { + var contentType = headers.get("Content-Type"); + var matcher = mboxBoundaryPattern.matcher(contentType); + if (matcher.matches()) { + return "--" + matcher.group(1); + } + } + return null; + } + private static final Pattern redundantTimeZonePattern = Pattern.compile("^(.*[-+\\d{4}]) \\(\\w+\\)$"); public static Email parse(String raw) { diff --git a/email/src/test/java/org/openjdk/skara/email/EmailTests.java b/email/src/test/java/org/openjdk/skara/email/EmailTests.java index 9fb38726e..92496fdf0 100644 --- a/email/src/test/java/org/openjdk/skara/email/EmailTests.java +++ b/email/src/test/java/org/openjdk/skara/email/EmailTests.java @@ -46,18 +46,18 @@ void parseSimple() { assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); } @Test void buildFrom() { var original = Email.create(EmailAddress.from("A", "a@b.c"), "Subject", "body") - .header("X", "y") - .header("Z", "a") - .recipient(EmailAddress.from("B", "b@b.c")) - .build(); + .header("X", "y") + .header("Z", "a") + .recipient(EmailAddress.from("B", "b@b.c")) + .build(); var copy = Email.from(original).build(); assertEquals("Subject", copy.subject()); assertEquals("body", copy.body()); @@ -70,14 +70,14 @@ void buildFrom() { @Test void reparent() { var first = Email.create(EmailAddress.from("A", "a@b.c"), "First", "body") - .recipient(EmailAddress.from("B", "b@b.c")) - .build(); + .recipient(EmailAddress.from("B", "b@b.c")) + .build(); var second = Email.create(EmailAddress.from("A", "a@b.c"), "Second", "body") - .recipient(EmailAddress.from("B", "b@b.c")) - .build(); + .recipient(EmailAddress.from("B", "b@b.c")) + .build(); var reply = Email.reply(first, "The reply", "reply body") - .author(EmailAddress.from("C", "c@b.c")) - .build(); + .author(EmailAddress.from("C", "c@b.c")) + .build(); assertEquals(first.id().toString(), reply.headerValue("In-Reply-To")); assertEquals(first.id().toString(), reply.headerValue("References")); var updated = Email.reparent(second, reply).build(); @@ -88,13 +88,13 @@ void reparent() { @Test void caseInsensitiveHeaders() { var mail = Email.parse("Message-ID: \n" + - "date: Wed, 27 Mar 2019 14:31:00 +0100\n" + - "SUBJECT: hello\n" + - "FRom: B \n" + - "tO: C , \n" + - "Extra-header: hello\n" + - "\n" + - "The body" + "date: Wed, 27 Mar 2019 14:31:00 +0100\n" + + "SUBJECT: hello\n" + + "FRom: B \n" + + "tO: C , \n" + + "Extra-header: hello\n" + + "\n" + + "The body" ); assertEquals(EmailAddress.from("a@b.c"), mail.id()); @@ -102,8 +102,8 @@ void caseInsensitiveHeaders() { assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); assertEquals(Set.of("Extra-header"), mail.headers()); assertEquals("hello", mail.headerValue("ExTra-HeaDer")); @@ -112,12 +112,12 @@ void caseInsensitiveHeaders() { @Test void redundantTimeZone() { var mail = Email.parse("Message-Id: \n" + - "Date: Wed, 27 Mar 2019 14:31:00 +0700 (PDT)\n" + - "Subject: hello\n" + - "From: B \n" + - "To: C , \n" + - "\n" + - "The body" + "Date: Wed, 27 Mar 2019 14:31:00 +0700 (PDT)\n" + + "Subject: hello\n" + + "From: B \n" + + "To: C , \n" + + "\n" + + "The body" ); assertEquals(ZonedDateTime.of(2019, 3, 27, 14, 31, 0, 0, ZoneOffset.ofHours(7)), mail.date()); assertEquals(EmailAddress.from("a@b.c"), mail.id()); @@ -125,20 +125,20 @@ void redundantTimeZone() { assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); } @Test void parseEncoded() { var mail = Email.parse("Message-Id: \n" + - "Date: Wed, 27 Mar 2019 14:31:00 +0100\n" + - "Subject: hello\n" + - "From: r.b at c.d (r =?iso-8859-1?Q?b=E4?=)\n" + - "To: C , \n" + - "\n" + - "The body" + "Date: Wed, 27 Mar 2019 14:31:00 +0100\n" + + "Subject: hello\n" + + "From: r.b at c.d (r =?iso-8859-1?Q?b=E4?=)\n" + + "To: C , \n" + + "\n" + + "The body" ); assertEquals(EmailAddress.from("a@b.c"), mail.id()); @@ -146,8 +146,38 @@ void parseEncoded() { assertEquals(EmailAddress.from("r bä", "r.b@c.d"), mail.author()); assertEquals(EmailAddress.from("r bä", "r.b@c.d"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); + assertEquals("The body", mail.body()); + } + + @Test + void parseContentType() { + var mail = Email.parse(""" + Message-Id: + Date: Wed, 27 Mar 2019 14:31:00 +0100 + Subject: hello + From: B + To: C , + Content-Type: multipart/mixed; boundary="===============3685582790409215631==" + + --===============3685582790409215631== + Content-Type: text/plain; charset="utf-8" + Content-Transfer-Encoding: 7bit + + The body + + --===============3685582790409215631== + """ + ); + + assertEquals(EmailAddress.from("a@b.c"), mail.id()); + assertEquals("hello", mail.subject()); + assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); + assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); + assertEquals(List.of(EmailAddress.from("C", "c@c.c"), + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); } } From 59f3dbe8f72fe1fd7f99f0d6c9929e8a4fd913f7 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 21 Nov 2025 13:59:26 -0800 Subject: [PATCH 06/10] Decode emails bodies --- .../java/org/openjdk/skara/email/Email.java | 69 +++++++++++------ .../org/openjdk/skara/email/EmailTests.java | 74 ++++++++++++++++--- 2 files changed, 111 insertions(+), 32 deletions(-) diff --git a/email/src/main/java/org/openjdk/skara/email/Email.java b/email/src/main/java/org/openjdk/skara/email/Email.java index 6f8dbe15e..0bd3cd182 100644 --- a/email/src/main/java/org/openjdk/skara/email/Email.java +++ b/email/src/main/java/org/openjdk/skara/email/Email.java @@ -22,11 +22,11 @@ */ package org.openjdk.skara.email; +import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; import java.time.format.*; import java.time.temporal.ChronoUnit; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -45,8 +45,10 @@ public class Email { "(\\r\\n){2}|(\\n){2}", Pattern.MULTILINE); private final static Pattern mboxMessageHeaderPattern = Pattern.compile( "^([-\\w]+): ((?:.(?!\\R\\w))*.)", Pattern.MULTILINE | Pattern.DOTALL); - private final static Pattern mboxMessageBodyHeaders = Pattern.compile( + private final static Pattern mimeHeadersPattern = Pattern.compile( "^(Content-Type|Content-Transfer-Encoding): .*"); + private final static Pattern quotedPrintableUtf8Pattern = Pattern.compile("=([0-9A-Fa-f]{2})=([0-9A-Fa-f]{2})"); + private final static Pattern quotedPrintablePattern = Pattern.compile("=([0-9A-Fa-f]{2})"); Email(EmailAddress id, ZonedDateTime date, List recipients, EmailAddress author, EmailAddress sender, String subject, String body, Map headers) { this.id = id; @@ -76,25 +78,47 @@ private static MboxMessage parseMboxMessage(String message) { ret.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); ret.headers.putAll(headers); - var boundary = parseBoundary(ret.headers); + var boundary = extractContentBoundary(ret.headers); if (boundary != null) { - // Content-Type: multipart/mixed; boundary="===============3685582790409215631==" - // - // --===============3685582790409215631== - // Content-Type: text/plain; charset="utf-8" - // Content-Transfer-Encoding: 7bit - // - // The body - // - // --===============3685582790409215631== - var firstEmptyLineRemoved = new AtomicBoolean(false); - ret.body = parts[1].lines() - .dropWhile(s -> !s.equals(boundary)) - .skip(1) - .dropWhile(s -> mboxMessageBodyHeaders.matcher(s).matches()) - .filter(s -> !(s.isEmpty() && !firstEmptyLineRemoved.getAndSet(true))) - .takeWhile(s -> !s.equals(boundary)) - .collect(Collectors.joining("\n")).stripTrailing(); + var body = new StringBuilder(); + var bodySections = parts[1].split("\\R?--" + boundary + "(?:--)?\\R"); + for (String bodySection : bodySections) { + if (bodySection.lines().findFirst().map(e -> mimeHeadersPattern.matcher(e).matches()).orElse(false)) { + var mimeHeaders = bodySection.lines() + .takeWhile(s -> !s.isEmpty()) + .map(mboxMessageHeaderPattern::matcher) + .filter(Matcher::matches) + .collect(Collectors.toMap(match -> match.group(1), match -> match.group(2))); + // Skip any non plain text part + if (mimeHeaders.containsKey("Content-Type") && !mimeHeaders.get("Content-Type").startsWith("text/plain")) { + continue; + } + // Remove the mime headers from the rest of the body section + var bodySectionBody = bodySection.split("\\R{2}", 2)[1]; + // Mailman3 encodes mail bodies with "quoted-printable". + if ("quoted-printable".equals(mimeHeaders.get("Content-Transfer-Encoding"))) { + // Remove soft line breaks + bodySectionBody = bodySectionBody + .replace("=\r\n", "") + .replace("=\n", ""); + if (mimeHeaders.get("Content-Type").contains("charset=\"utf-8\"")) { + // Decode UTF-8 characters which are encoded as pairs of =XX=YY. + bodySectionBody = quotedPrintableUtf8Pattern.matcher(bodySectionBody).replaceAll(m -> { + var bytes = new byte[]{(byte) Integer.parseInt(m.group(1), 16), + (byte) Integer.parseInt(m.group(2), 16)}; + return new String(bytes, StandardCharsets.UTF_8); + }); + } + // Replace all possibly remaining single instances of =XX. + bodySectionBody = quotedPrintablePattern.matcher(bodySectionBody).replaceAll(m -> + Character.toString((char) Integer.parseInt(m.group(1), 16))); + } + body.append(bodySectionBody.stripTrailing()); + } else { + body.append(bodySection.stripTrailing()); + } + } + ret.body = body.toString(); } else { ret.body = parts[1].stripTrailing(); } @@ -103,12 +127,13 @@ private static MboxMessage parseMboxMessage(String message) { private final static Pattern mboxBoundaryPattern = Pattern.compile(".*boundary=\"([^\"]*)\".*"); - private static String parseBoundary(Map headers) { + // Content-Type: multipart/mixed; boundary="===============3685582790409215631==" + private static String extractContentBoundary(Map headers) { if (headers.containsKey("Content-Type")) { var contentType = headers.get("Content-Type"); var matcher = mboxBoundaryPattern.matcher(contentType); if (matcher.matches()) { - return "--" + matcher.group(1); + return matcher.group(1); } } return null; diff --git a/email/src/test/java/org/openjdk/skara/email/EmailTests.java b/email/src/test/java/org/openjdk/skara/email/EmailTests.java index 92496fdf0..dee667ee7 100644 --- a/email/src/test/java/org/openjdk/skara/email/EmailTests.java +++ b/email/src/test/java/org/openjdk/skara/email/EmailTests.java @@ -152,7 +152,7 @@ void parseEncoded() { } @Test - void parseContentType() { + void parseContentType7bit() { var mail = Email.parse(""" Message-Id: Date: Wed, 27 Mar 2019 14:31:00 +0100 @@ -165,19 +165,73 @@ void parseContentType() { Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit - The body + The body text + --===============3685582790409215631==-- + """ + ); + + assertEquals("The body text", mail.body()); + } + + @Test + void parseContentTypeQuotedPrintable() { + var foo = "räksmörgås"; + var mail = Email.parse(""" + Message-Id: + Date: Wed, 27 Mar 2019 14:31:00 +0100 + Subject: hello + From: B + To: C , + Content-Type: multipart/mixed; boundary="===============3685582790409215631==" + --===============3685582790409215631== + Content-Type: text/plain; charset="utf-8" + Content-Transfer-Encoding: quoted-printable + + A response with weird characters r=C3=A4ksm=C3=B6rg=C3=A5s and a line longer = + than 76=20 + characters. + + --===============3685582790409215631==-- """ ); - assertEquals(EmailAddress.from("a@b.c"), mail.id()); - assertEquals("hello", mail.subject()); - assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); - assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); - assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); - assertEquals("The body", mail.body()); + assertEquals("A response with weird characters räksmörgås and a line longer than 76 \ncharacters.", mail.body()); + } + + @Test + void parseContentTypeMultipart() { + var mail = Email.parse(""" + Message-Id: + Date: Wed, 27 Mar 2019 14:31:00 +0100 + Subject: hello + From: B + To: C , + Content-Type: multipart/mixed; boundary="===============3685582790409215631==" + + --===============3685582790409215631== + Content-Type: text/plain; charset="utf-8" + Content-Transfer-Encoding: 7bit + + The body text + + --===============3685582790409215631== + Content-Type: text/html + Content-Transfer-Encoding: base64 + Content-Disposition: attachment; filename="attachment.html" + MIME-Version: 1.0 + + PCFET0NUWVBFIGh0bWw+PGh0bWw+PGhlYWQ+CjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlw + ZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KICA8L2hlYWQ+CiAgPGJvZHk+ + CiAgICA8aDE+VGhpcyBpcyBhbiBlbWFpbCB3aXRoIGZvcm1hdHRpbmc8L2gxPgogICAgPHA+UGFy + YWdyYXBoIHRleHQuPC9wPgogICAgPHByZT5QcmVmb3JtYXQgdGV4dC48L3ByZT4KICA8L2JvZHk+ + CjwvaHRtbD4K + + --===============3685582790409215631==-- + """ + ); + + assertEquals("The body text", mail.body()); } } From b709e0b269b5e689da50890f577df26ddb835723 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 21 Nov 2025 14:59:35 -0800 Subject: [PATCH 07/10] cleanup --- .../mlbridge/MailingListBridgeBotFactory.java | 21 +----- .../MailingListBridgeBotFactoryTest.java | 10 +-- .../MailingListNotifierFactory.java | 3 - .../org/openjdk/skara/email/EmailTests.java | 75 +++++++++---------- .../mailinglist/mailman/Mailman2Server.java | 22 ++++++ .../mailinglist/mailman/Mailman3Server.java | 22 ++++++ .../mailinglist/mailman/SendOnlyServer.java | 22 ++++++ .../mailinglist/Mailman3IntegrationTests.java | 22 ++++++ .../skara/mailinglist/Mailman3Tests.java | 2 +- .../openjdk/skara/test/TestMailmanServer.java | 1 - 10 files changed, 131 insertions(+), 69 deletions(-) diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java index da3629976..7504c3507 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java @@ -84,7 +84,6 @@ public List create(BotConfiguration configuration) { archiveType = specific.get("server").get("type").asString(); } var listSmtp = specific.get("server").get("smtp").asString(); - var interval = specific.get("server").contains("interval") ? Duration.parse(specific.get("server").get("interval").asString()) : Duration.ofSeconds(1); var webrevHTMLRepo = configuration.repository(specific.get("webrevs").get("repository").get("html").asString()); var webrevJSONRepo = configuration.repository(specific.get("webrevs").get("repository").get("json").asString()); @@ -127,22 +126,6 @@ public List create(BotConfiguration configuration) { .collect(Collectors.toMap(JSONObject.Field::name, field -> field.value().asString())) : Map.of(); - // Allow overriding the archive pre repository - URI repoListArchive = null; - if (repoConfig.contains("server") && repoConfig.get("server").contains("archive")) { - repoListArchive = URIBuilder.base(repoConfig.get("server").get("archive").asString()).build(); - } - MailingListServer repoMailmanServer; - if (repoListArchive != null) { - String repoArchiveType = archiveType; - if (repoConfig.get("server").contains("type")) { - repoArchiveType = repoConfig.get("server").get("type").asString(); - } - repoMailmanServer = createMailmanServer(repoArchiveType, repoListArchive, listSmtp, useEtag); - } else { - repoMailmanServer = mailmanServer; - } - var lists = parseLists(repoConfig.get("lists")); if (!repoConfig.contains("bidirectional") || repoConfig.get("bidirectional").asBoolean()) { var listNamesForReading = new HashSet(); @@ -156,7 +139,7 @@ public List create(BotConfiguration configuration) { // Reuse MailingListReaders with the exact same set of mailing lists between bots // to benefit more from cached results. if (!mailingListReaderMap.containsKey(listsForReading)) { - mailingListReaderMap.put(listsForReading, repoMailmanServer.getListReader(listsForReading.toArray(new String[0]))); + mailingListReaderMap.put(listsForReading, mailmanServer.getListReader(listsForReading.toArray(new String[0]))); } var bot = new MailingListArchiveReaderBot(mailingListReaderMap.get(listsForReading), hostedRepository); ret.add(bot); @@ -196,7 +179,7 @@ public List create(BotConfiguration configuration) { .headers(headers) .cooldown(cooldown) .seedStorage(configuration.storageFolder().resolve("seeds")) - .mailingListServer(repoMailmanServer); + .mailingListServer(mailmanServer); if (repoConfig.contains("reponame")) { botBuilder.repoInSubject(repoConfig.get("reponame").asBoolean()); diff --git a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java index ce92956b4..17735ae72 100644 --- a/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java +++ b/bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactoryTest.java @@ -137,11 +137,7 @@ public void testCreate() { ] } ], - "issues": "https://test.test.com/issueProject", - "server": { - "archive": "https://test.example.com/archive", - "type": "mailman3" - } + "issues": "https://test.test.com/issueProject" } ] } @@ -182,7 +178,7 @@ public void testCreate() { (MailingListArchiveReaderBot) mailingListArchiveReaderBots.get(1); assertEquals("MailingListArchiveReaderBot@repo5", mailingListArchiveReaderBot2.toString()); MailingListReader readerBot2MailingListReader = mailingListArchiveReaderBot2.mailingListReader(); - assertTrue(readerBot2MailingListReader.getClass().getName().contains("Mailman3"), + assertTrue(readerBot2MailingListReader.getClass().getName().contains("Mailman2"), readerBot2MailingListReader.getClass().getName()); MailingListBridgeBot mailingListBridgeBot1 = (MailingListBridgeBot) mailingListBridgeBots.get(0); @@ -243,7 +239,7 @@ public void testCreate() { assertTrue(mailingListBridgeBot3.repoInSubject()); assertEquals("master", mailingListBridgeBot3.branchInSubject().toString()); MailingListServer bridgeBot3MailingListServer = mailingListBridgeBot3.mailingListServer(); - assertTrue(bridgeBot3MailingListServer.getClass().getName().contains("Mailman3")); + assertTrue(bridgeBot3MailingListServer.getClass().getName().contains("Mailman2")); } } } diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java index c7bc22eb8..d421c4d0f 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/mailinglist/MailingListNotifierFactory.java @@ -22,14 +22,11 @@ */ package org.openjdk.skara.bots.notify.mailinglist; -import java.util.Optional; import org.openjdk.skara.bot.BotConfiguration; import org.openjdk.skara.bots.notify.*; import org.openjdk.skara.email.EmailAddress; import org.openjdk.skara.json.JSONObject; -import org.openjdk.skara.mailinglist.MailingListServer; import org.openjdk.skara.mailinglist.MailingListServerFactory; -import org.openjdk.skara.network.URIBuilder; import java.time.Duration; import java.util.regex.Pattern; diff --git a/email/src/test/java/org/openjdk/skara/email/EmailTests.java b/email/src/test/java/org/openjdk/skara/email/EmailTests.java index dee667ee7..5dda2896d 100644 --- a/email/src/test/java/org/openjdk/skara/email/EmailTests.java +++ b/email/src/test/java/org/openjdk/skara/email/EmailTests.java @@ -46,18 +46,18 @@ void parseSimple() { assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); } @Test void buildFrom() { var original = Email.create(EmailAddress.from("A", "a@b.c"), "Subject", "body") - .header("X", "y") - .header("Z", "a") - .recipient(EmailAddress.from("B", "b@b.c")) - .build(); + .header("X", "y") + .header("Z", "a") + .recipient(EmailAddress.from("B", "b@b.c")) + .build(); var copy = Email.from(original).build(); assertEquals("Subject", copy.subject()); assertEquals("body", copy.body()); @@ -70,14 +70,14 @@ void buildFrom() { @Test void reparent() { var first = Email.create(EmailAddress.from("A", "a@b.c"), "First", "body") - .recipient(EmailAddress.from("B", "b@b.c")) - .build(); + .recipient(EmailAddress.from("B", "b@b.c")) + .build(); var second = Email.create(EmailAddress.from("A", "a@b.c"), "Second", "body") - .recipient(EmailAddress.from("B", "b@b.c")) - .build(); + .recipient(EmailAddress.from("B", "b@b.c")) + .build(); var reply = Email.reply(first, "The reply", "reply body") - .author(EmailAddress.from("C", "c@b.c")) - .build(); + .author(EmailAddress.from("C", "c@b.c")) + .build(); assertEquals(first.id().toString(), reply.headerValue("In-Reply-To")); assertEquals(first.id().toString(), reply.headerValue("References")); var updated = Email.reparent(second, reply).build(); @@ -88,13 +88,13 @@ void reparent() { @Test void caseInsensitiveHeaders() { var mail = Email.parse("Message-ID: \n" + - "date: Wed, 27 Mar 2019 14:31:00 +0100\n" + - "SUBJECT: hello\n" + - "FRom: B \n" + - "tO: C , \n" + - "Extra-header: hello\n" + - "\n" + - "The body" + "date: Wed, 27 Mar 2019 14:31:00 +0100\n" + + "SUBJECT: hello\n" + + "FRom: B \n" + + "tO: C , \n" + + "Extra-header: hello\n" + + "\n" + + "The body" ); assertEquals(EmailAddress.from("a@b.c"), mail.id()); @@ -102,8 +102,8 @@ void caseInsensitiveHeaders() { assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); assertEquals(Set.of("Extra-header"), mail.headers()); assertEquals("hello", mail.headerValue("ExTra-HeaDer")); @@ -112,12 +112,12 @@ void caseInsensitiveHeaders() { @Test void redundantTimeZone() { var mail = Email.parse("Message-Id: \n" + - "Date: Wed, 27 Mar 2019 14:31:00 +0700 (PDT)\n" + - "Subject: hello\n" + - "From: B \n" + - "To: C , \n" + - "\n" + - "The body" + "Date: Wed, 27 Mar 2019 14:31:00 +0700 (PDT)\n" + + "Subject: hello\n" + + "From: B \n" + + "To: C , \n" + + "\n" + + "The body" ); assertEquals(ZonedDateTime.of(2019, 3, 27, 14, 31, 0, 0, ZoneOffset.ofHours(7)), mail.date()); assertEquals(EmailAddress.from("a@b.c"), mail.id()); @@ -125,20 +125,20 @@ void redundantTimeZone() { assertEquals(EmailAddress.from("B", "b@b.c"), mail.author()); assertEquals(EmailAddress.from("B", "b@b.c"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); } @Test void parseEncoded() { var mail = Email.parse("Message-Id: \n" + - "Date: Wed, 27 Mar 2019 14:31:00 +0100\n" + - "Subject: hello\n" + - "From: r.b at c.d (r =?iso-8859-1?Q?b=E4?=)\n" + - "To: C , \n" + - "\n" + - "The body" + "Date: Wed, 27 Mar 2019 14:31:00 +0100\n" + + "Subject: hello\n" + + "From: r.b at c.d (r =?iso-8859-1?Q?b=E4?=)\n" + + "To: C , \n" + + "\n" + + "The body" ); assertEquals(EmailAddress.from("a@b.c"), mail.id()); @@ -146,8 +146,8 @@ void parseEncoded() { assertEquals(EmailAddress.from("r bä", "r.b@c.d"), mail.author()); assertEquals(EmailAddress.from("r bä", "r.b@c.d"), mail.sender()); assertEquals(List.of(EmailAddress.from("C", "c@c.c"), - EmailAddress.from("d@d.c")), - mail.recipients()); + EmailAddress.from("d@d.c")), + mail.recipients()); assertEquals("The body", mail.body()); } @@ -176,7 +176,6 @@ void parseContentType7bit() { @Test void parseContentTypeQuotedPrintable() { - var foo = "räksmörgås"; var mail = Email.parse(""" Message-Id: Date: Wed, 27 Mar 2019 14:31:00 +0100 diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java index 5fd5876fd..ca9f80e3b 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman2Server.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ package org.openjdk.skara.mailinglist.mailman; import java.net.URI; diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java index fa86d9ab9..c6c5465bd 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ package org.openjdk.skara.mailinglist.mailman; import java.net.URI; diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java index 82659a924..a55a51712 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/SendOnlyServer.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ package org.openjdk.skara.mailinglist.mailman; import java.time.Duration; diff --git a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java index f4a8cd73a..1df267654 100644 --- a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java +++ b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3IntegrationTests.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ package org.openjdk.skara.mailinglist; import java.time.Duration; diff --git a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java index 397be4187..ee961f8a5 100644 --- a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java +++ b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java b/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java index 7df30bc4d..ec8c51858 100644 --- a/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java +++ b/test/src/main/java/org/openjdk/skara/test/TestMailmanServer.java @@ -23,7 +23,6 @@ package org.openjdk.skara.test; import com.sun.net.httpserver.*; -import java.nio.charset.Charset; import java.time.LocalDate; import java.time.ZoneId; import java.time.ZonedDateTime; From 97f0264948846c80032e8bb6e17cc7b6d939f4e8 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 24 Nov 2025 12:28:03 -0800 Subject: [PATCH 08/10] Better query strategy for mailman3 --- .../mlbridge/MailingListBridgeBotFactory.java | 2 +- .../mailinglist/MailingListServerFactory.java | 6 +- .../mailinglist/mailman/Mailman3Server.java | 13 +- .../mailman/MailmanListReader.java | 56 ++++++--- .../skara/mailinglist/Mailman3Tests.java | 118 +++++++----------- 5 files changed, 101 insertions(+), 94 deletions(-) diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java index 7504c3507..f5855a374 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java @@ -198,7 +198,7 @@ private static MailingListServer createMailmanServer(String archiveType, URI lis if (archiveType == null || archiveType.equals("mailman2")) { mailmanServer = MailingListServerFactory.createMailman2Server(listArchive, listSmtp, Duration.ZERO, useEtag); } else if (archiveType.equals("mailman3")) { - mailmanServer = MailingListServerFactory.createMailman3Server(listArchive, listSmtp, Duration.ZERO, useEtag); + mailmanServer = MailingListServerFactory.createMailman3Server(listArchive, listSmtp, Duration.ZERO); } else { throw new RuntimeException("Invalid server archive type: " + archiveType); } diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java index ef819efa9..70caa0adc 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/MailingListServerFactory.java @@ -41,11 +41,7 @@ public static MailingListServer createMailman2Server(URI archive, String smtp, D } public static MailingListServer createMailman3Server(URI archive, String smtp, Duration sendInterval) { - return new Mailman3Server(archive, smtp, sendInterval, false); - } - - public static MailingListServer createMailman3Server(URI archive, String smtp, Duration sendInterval, boolean useEtag) { - return new Mailman3Server(archive, smtp, sendInterval, useEtag); + return new Mailman3Server(archive, smtp, sendInterval); } public static MailingListServer createSendOnlyServer(String smtp, Duration sendInterval) { diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java index c6c5465bd..00c8e9051 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/Mailman3Server.java @@ -24,13 +24,20 @@ import java.net.URI; import java.time.Duration; +import java.time.ZonedDateTime; import java.util.Arrays; import org.openjdk.skara.mailinglist.MailingListReader; public class Mailman3Server extends MailmanServer { + private final ZonedDateTime startTime; - public Mailman3Server(URI archive, String smtpServer, Duration sendInterval, boolean useEtag) { - super(archive, smtpServer, sendInterval, useEtag); + public Mailman3Server(URI archive, String smtpServer, Duration sendInterval, ZonedDateTime startTime) { + super(archive, smtpServer, sendInterval, false); + this.startTime = startTime; + } + + public Mailman3Server(URI archive, String smtpServer, Duration sendInterval) { + this(archive, smtpServer, sendInterval, ZonedDateTime.now()); } URI getArchiveUri() { @@ -39,6 +46,6 @@ URI getArchiveUri() { @Override public MailingListReader getListReader(String... listNames) { - return new Mailman3ListReader(this, Arrays.asList(listNames), useEtag); + return new Mailman3ListReader(this, Arrays.asList(listNames), startTime); } } diff --git a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java index 4b8eabc65..ad7170583 100644 --- a/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java +++ b/mailinglist/src/main/java/org/openjdk/skara/mailinglist/mailman/MailmanListReader.java @@ -183,34 +183,62 @@ public List conversations(Duration maxAge) { class Mailman3ListReader extends MailmanListReader { private final Mailman3Server server; + private final ZonedDateTime startTime; - Mailman3ListReader(Mailman3Server server, Collection names, boolean useEtag) { - super(names, useEtag); + Mailman3ListReader(Mailman3Server server, Collection names, ZonedDateTime startTime) { + // Mailman3 does not support etag for mbox API + super(names, false); this.server = server; + this.startTime = startTime; } + /** + * Reads all emails newer than maxAge. Reads everything older than start + * time in one go and caches that result. This chunk will always read start + * time minus max age. Emails older than now minus max age are filtered out + * later. Chunks newer than start time are read one day at a time, each day + * getting cached when the next day starts. This means only the current day + * is refreshed each time this method is called. + * + * @param maxAge Maximum age of emails to read relative to the start time. + * @return Emails sorted in conversations + */ @Override public List conversations(Duration maxAge) { var now = ZonedDateTime.now(); - var start = now.minus(maxAge).withDayOfMonth(1); - var query = Map.of("start", List.of(start.format(DateTimeFormatter.ISO_LOCAL_DATE))); + // First interval is everything before start time + var start = startTime.minus(maxAge); + var end = startTime.plusDays(1); + var emails = new ArrayList(); var newContent = false; // https://mail-dev.example.com/archives/list/skara-test@mail-dev.example.com/export/foo.mbox.gz?start=2024-10-25&end=2025-10-25 - for (String name : names) { - var mboxUri = URIBuilder.base(server.getArchiveUri()).appendPath("list/").appendPath(name) - .appendPath("@").appendPath(server.getArchiveUri().getHost()) - .appendPath("/export/foo.mbox.gz").setQuery(query).build(); - var mboxResponse = getPage(mboxUri); - if (mboxResponse.isPresent()) { + + while (start.isBefore(now)) { + var query = Map.of("start", List.of(start.format(DateTimeFormatter.ISO_LOCAL_DATE)), + "end", List.of(end.format(DateTimeFormatter.ISO_LOCAL_DATE))); + for (String name : names) { + var mboxUri = URIBuilder.base(server.getArchiveUri()).appendPath("list/").appendPath(name) + .appendPath("@").appendPath(server.getArchiveUri().getHost()) + .appendPath("/export/foo.mbox.gz").setQuery(query).build(); var sender = EmailAddress.from(name + "@" + server.getArchiveUri().getHost()); - if (mboxResponse.get().statusCode() == 304) { - emails.addAll(0, Mbox.splitMbox(gunzipToString(pageCache.get(mboxUri).body()), sender)); + // For archives older than today, always use cached results + if (end.isBefore(now) && pageCache.containsKey(mboxUri)) { + var cachedResponse = pageCache.get(mboxUri); + if (cachedResponse != null && cachedResponse.statusCode() != 404) { + emails.addAll(0, Mbox.splitMbox(gunzipToString(cachedResponse.body()), sender)); + } } else { - emails.addAll(0, Mbox.splitMbox(gunzipToString(mboxResponse.get().body()), sender)); - newContent = true; + var mboxResponse = getPage(mboxUri); + if (mboxResponse.isPresent()) { + emails.addAll(0, Mbox.splitMbox(gunzipToString(mboxResponse.get().body()), sender)); + newContent = true; + } } } + // Every interval after the first is one day + start = end; + end = end.plusDays(1); } if (newContent) { diff --git a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java index ee961f8a5..c641c66df 100644 --- a/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java +++ b/mailinglist/src/test/java/org/openjdk/skara/mailinglist/Mailman3Tests.java @@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test; import org.openjdk.skara.email.Email; import org.openjdk.skara.email.EmailAddress; +import org.openjdk.skara.mailinglist.mailman.Mailman3Server; import org.openjdk.skara.test.TestMailmanServer; import static org.junit.jupiter.api.Assertions.*; @@ -104,40 +105,6 @@ void replies() throws IOException { } } - @Test - void cached() throws IOException { - try (var testServer = TestMailmanServer.createV3()) { - var listAddress = testServer.createList("test"); - var mailmanServer = MailingListServerFactory.createMailman3Server(testServer.getArchive(), testServer.getSMTP(), - Duration.ZERO, true); - var mailmanList = mailmanServer.getListReader(listAddress); - var sender = EmailAddress.from("Test", "test@test.email"); - var mail = Email.create(sender, "Subject", "Body") - .recipient(EmailAddress.parse(listAddress)) - .build(); - mailmanServer.post(mail); - testServer.processIncoming(); - - var expectedMail = Email.from(mail) - .sender(EmailAddress.parse(listAddress)) - .build(); - { - var conversations = mailmanList.conversations(Duration.ofDays(1)); - assertEquals(1, conversations.size()); - var conversation = conversations.get(0); - assertEquals(expectedMail, conversation.first()); - assertFalse(testServer.lastResponseCached()); - } - { - var conversations = mailmanList.conversations(Duration.ofDays(1)); - assertEquals(1, conversations.size()); - var conversation = conversations.get(0); - assertEquals(expectedMail, conversation.first()); - assertTrue(testServer.lastResponseCached()); - } - } - } - @Test void interval() throws IOException { try (var testServer = TestMailmanServer.createV3()) { @@ -171,71 +138,80 @@ void interval() throws IOException { } @Test - void poll3months() throws Exception { + void poll3days() throws Exception { try (var testServer = TestMailmanServer.createV3()) { var listAddress = testServer.createList("test"); - var mailmanServer = MailingListServerFactory.createMailman3Server(testServer.getArchive(), - testServer.getSMTP(), Duration.ZERO); + var now = ZonedDateTime.now(); + var mailmanServer = new Mailman3Server(testServer.getArchive(), + testServer.getSMTP(), Duration.ZERO, now.minusDays(2)); var mailmanList = mailmanServer.getListReader(listAddress); var sender = EmailAddress.from("Test", "test@test.email"); - var now = ZonedDateTime.now(); - var mail2monthsAgo = Email.create(sender, "Subject 2 months ago", "Body 1") - .recipient(EmailAddress.parse(listAddress)) - .date(now.minusMonths(2)) - .build(); - var mail1monthAgo = Email.create(sender, "Subject 1 month ago", "Body 2") - .recipient(EmailAddress.parse(listAddress)) - .date(now.minusMonths(1)) - .build(); - var mailNow = Email.create(sender, "Subject now", "Body 3") - .recipient(EmailAddress.parse(listAddress)) - .build(); - - var duration2Months = Duration.between(now.minusMonths(2), now); + + var duration3Days = Duration.between(now.minusDays(3), now); + { - var conversations = mailmanList.conversations(duration2Months); - assertEquals(0, conversations.size()); - assertEquals(1, testServer.callCount(), "Server wasn't called once"); + // A 2 days old should be picked up + var mail2daysAgo = Email.create(sender, "Subject 2 day2 ago", "Body 1") + .recipient(EmailAddress.parse(listAddress)) + .date(now.minusDays(2)) + .build(); + mailmanServer.post(mail2daysAgo); + testServer.processIncoming(); + testServer.resetCallCount(); + var conversations = mailmanList.conversations(duration3Days); + assertEquals(1, conversations.size()); + assertEquals(3, testServer.callCount(), + "Server wasn't for initial interval plus every day since start time"); } { - // A 2 months old mail should not be picked up now as old results should be cached - mailmanServer.post(mail2monthsAgo); + // A 2 days old mail should not be picked up now as old results should be cached + var mail2daysAgo2 = Email.create(sender, "Subject 2 days ago 2", "Body 2") + .recipient(EmailAddress.parse(listAddress)) + .date(now.minusDays(2)) + .build(); + mailmanServer.post(mail2daysAgo2); testServer.processIncoming(); testServer.resetCallCount(); - var conversations = mailmanList.conversations(duration2Months); - assertEquals(0, conversations.size()); - // + var conversations = mailmanList.conversations(duration3Days); + assertEquals(1, conversations.size()); assertEquals(1, testServer.callCount(), "Server wasn't called once"); } { - // A mail from last month should be found - mailmanServer.post(mail1monthAgo); + // A 1-day-old mail should not be picked up now as old results should be cached + var mail1dayAgo = Email.create(sender, "Subject 1 day ago", "Body 2") + .recipient(EmailAddress.parse(listAddress)) + .date(now.minusDays(1)) + .build(); + mailmanServer.post(mail1dayAgo); testServer.processIncoming(); testServer.resetCallCount(); - var conversations = mailmanList.conversations(duration2Months); + var conversations = mailmanList.conversations(duration3Days); assertEquals(1, conversations.size()); assertEquals(1, testServer.callCount()); } { // A current mail should be found + var mailNow = Email.create(sender, "Subject now", "Body 3") + .recipient(EmailAddress.parse(listAddress)) + .build(); mailmanServer.post(mailNow); testServer.processIncoming(); testServer.resetCallCount(); - var conversations = mailmanList.conversations(duration2Months); + var conversations = mailmanList.conversations(duration3Days); assertEquals(2, conversations.size()); assertEquals(1, testServer.callCount()); } { - // Another mail from last month should be found - var mail1monthAgo2 = Email.create(sender, "Subject 1 month ago 2", "Body 2") + // Another mail from last month should not be found + var mail1dayAgo2 = Email.create(sender, "Subject 1 day ago 2", "Body 2") .recipient(EmailAddress.parse(listAddress)) - .date(now.minusMonths(1)) + .date(now.minusDays(1)) .build(); - mailmanServer.post(mail1monthAgo2); + mailmanServer.post(mail1dayAgo2); testServer.processIncoming(); testServer.resetCallCount(); - var conversations = mailmanList.conversations(duration2Months); - assertEquals(3, conversations.size()); + var conversations = mailmanList.conversations(duration3Days); + assertEquals(2, conversations.size()); assertEquals(1, testServer.callCount()); } { @@ -246,8 +222,8 @@ void poll3months() throws Exception { mailmanServer.post(mailNow2); testServer.processIncoming(); testServer.resetCallCount(); - var conversations = mailmanList.conversations(duration2Months); - assertEquals(4, conversations.size()); + var conversations = mailmanList.conversations(duration3Days); + assertEquals(3, conversations.size()); assertEquals(1, testServer.callCount()); } } From e301943bdd66f986e7da4e613bbaef9d5c293115 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Tue, 25 Nov 2025 10:59:16 -0800 Subject: [PATCH 09/10] Fix whitespace --- email/src/test/java/org/openjdk/skara/email/EmailTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/email/src/test/java/org/openjdk/skara/email/EmailTests.java b/email/src/test/java/org/openjdk/skara/email/EmailTests.java index 5dda2896d..52081dd2f 100644 --- a/email/src/test/java/org/openjdk/skara/email/EmailTests.java +++ b/email/src/test/java/org/openjdk/skara/email/EmailTests.java @@ -164,9 +164,9 @@ void parseContentType7bit() { --===============3685582790409215631== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit - + The body text - + --===============3685582790409215631==-- """ ); From 6e5f6caeebe5e70707b16e393e4fc5f3bb0302ed Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 26 Nov 2025 14:10:04 -0800 Subject: [PATCH 10/10] Restored send interval --- .../bots/mlbridge/MailingListBridgeBotFactory.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java index f5855a374..d259aa8b7 100644 --- a/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java +++ b/bots/mlbridge/src/main/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotFactory.java @@ -84,6 +84,8 @@ public List create(BotConfiguration configuration) { archiveType = specific.get("server").get("type").asString(); } var listSmtp = specific.get("server").get("smtp").asString(); + var interval = specific.get("server").contains("interval") ? + Duration.parse(specific.get("server").get("interval").asString()) : Duration.ofSeconds(1); var webrevHTMLRepo = configuration.repository(specific.get("webrevs").get("repository").get("html").asString()); var webrevJSONRepo = configuration.repository(specific.get("webrevs").get("repository").get("json").asString()); @@ -106,7 +108,7 @@ public List create(BotConfiguration configuration) { if (specific.get("server").contains("etag")) { useEtag = specific.get("server").get("etag").asBoolean(); } - MailingListServer mailmanServer = createMailmanServer(archiveType, listArchive, listSmtp, useEtag); + MailingListServer mailmanServer = createMailmanServer(archiveType, listArchive, listSmtp, interval, useEtag); var mailingListReaderMap = new HashMap, MailingListReader>(); @@ -193,12 +195,13 @@ public List create(BotConfiguration configuration) { return ret; } - private static MailingListServer createMailmanServer(String archiveType, URI listArchive, String listSmtp, boolean useEtag) { + private static MailingListServer createMailmanServer(String archiveType, URI listArchive, String listSmtp, + Duration sendInterval, boolean useEtag) { MailingListServer mailmanServer; if (archiveType == null || archiveType.equals("mailman2")) { - mailmanServer = MailingListServerFactory.createMailman2Server(listArchive, listSmtp, Duration.ZERO, useEtag); + mailmanServer = MailingListServerFactory.createMailman2Server(listArchive, listSmtp, sendInterval, useEtag); } else if (archiveType.equals("mailman3")) { - mailmanServer = MailingListServerFactory.createMailman3Server(listArchive, listSmtp, Duration.ZERO); + mailmanServer = MailingListServerFactory.createMailman3Server(listArchive, listSmtp, sendInterval); } else { throw new RuntimeException("Invalid server archive type: " + archiveType); }