(e.g. INBOX, Drafts, ...) / <*.eml> below " + sourceDirectory + " for " + emailPath);
+ }
+
+ // Extract email as first folder
+ String email = emailPath.getName(sourceNameCount).toString();
+ GreenMailUser user = userManager.getUserByEmail(email);
+ if (null == user) {
+ try {
+ user = userManager.createUser(email, email, email);
+ } catch (UserException e) {
+ throw new IllegalStateException("Can not create user for email " + email, e);
+ }
+ }
+
+ // Extract and optionally create intermediate folders
+ MailFolder folder = null;
+ folder = store.getMailbox(getUserBaseMailboxName(imapHostManager, user));
+ for (int i = sourceNameCount + 1; i < emailPathNameCount - 1; i++) {
+ String namePart = emailPath.getName(i).toString();
+ MailFolder child = store.getMailbox(folder, namePart);
+ if (null == child) {
+ child = store.createMailbox(folder, namePart, true);
+ }
+ folder = child;
+ }
+
+ if (Files.isRegularFile(emailPath) && emailPath.toString().endsWith(".eml")) {
+ try (InputStream source = Files.newInputStream(emailPath)) {
+ final MimeMessage loadedMsg = new MimeMessage(session, source);
+ if (log.isDebugEnabled()) {
+ log.debug("Loading email for {} from {} ...", user.getEmail(), emailPath);
+ }
+ folder.store(loadedMsg);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Can not load email " + emailPath, e);
+ }
+ }
+ }
+
+ private String getUserBaseMailboxName(ImapHostManager imapHostManager, GreenMailUser user) throws FolderException {
+ String inbox = imapHostManager.getInbox(user).getFullName();
+ if (!inbox.toUpperCase().endsWith(ImapConstants.INBOX_NAME)) {
+ throw new IllegalStateException("Mail folder '" + inbox + "' is not expected " + ImapConstants.INBOX_NAME + " folder");
+ }
+ return inbox.substring(0, inbox.length() - ImapConstants.INBOX_NAME.length());
+ }
}
diff --git a/greenmail-core/src/main/java/com/icegreen/greenmail/util/GreenMailProxy.java b/greenmail-core/src/main/java/com/icegreen/greenmail/util/GreenMailProxy.java
index 7e353283ac..78930cc2e5 100644
--- a/greenmail-core/src/main/java/com/icegreen/greenmail/util/GreenMailProxy.java
+++ b/greenmail-core/src/main/java/com/icegreen/greenmail/util/GreenMailProxy.java
@@ -1,6 +1,7 @@
package com.icegreen.greenmail.util;
import com.icegreen.greenmail.Managers;
+import com.icegreen.greenmail.base.GreenMailOperations;
import com.icegreen.greenmail.configuration.ConfiguredGreenMail;
import com.icegreen.greenmail.imap.ImapServer;
import com.icegreen.greenmail.pop3.Pop3Server;
@@ -10,6 +11,9 @@
import com.icegreen.greenmail.user.UserManager;
import jakarta.mail.internet.MimeMessage;
+
+import java.io.IOException;
+import java.nio.file.Path;
import java.util.Properties;
/**
@@ -118,6 +122,11 @@ public void purgeEmailFromAllMailboxes() throws FolderException {
getGreenMail().purgeEmailFromAllMailboxes();
}
+ @Override
+ public GreenMailOperations loadEmails(Path path) throws FolderException, IOException {
+ return getGreenMail().loadEmails(path);
+ }
+
/**
* @return Greenmail instance provided by child class
*/
diff --git a/greenmail-core/src/test/java/com/icegreen/greenmail/examples/ExamplePreloadMailFromFsTest.java b/greenmail-core/src/test/java/com/icegreen/greenmail/examples/ExamplePreloadMailFromFsTest.java
index 8d2e773490..ba60c612ea 100644
--- a/greenmail-core/src/test/java/com/icegreen/greenmail/examples/ExamplePreloadMailFromFsTest.java
+++ b/greenmail-core/src/test/java/com/icegreen/greenmail/examples/ExamplePreloadMailFromFsTest.java
@@ -1,5 +1,6 @@
package com.icegreen.greenmail.examples;
+import com.icegreen.greenmail.imap.ImapConstants;
import com.icegreen.greenmail.imap.ImapHostManager;
import com.icegreen.greenmail.junit.GreenMailRule;
import com.icegreen.greenmail.user.GreenMailUser;
@@ -15,14 +16,19 @@
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
+/**
+ * Example for loading Emails from EML file.
+ *
+ * For preloading an existing directory structure, check out {@link com.icegreen.greenmail.util.PreLoadEmailsTest}
+ */
public class ExamplePreloadMailFromFsTest {
@Rule
public final GreenMailRule greenMail = new GreenMailRule(ServerSetupTest.SMTP);
- public static final String EML_FILE_NAME = ExamplePreloadMailFromFsTest.class.getName() + ".eml";
+ public static final String EML_FILE_NAME = ExamplePreloadMailFromFsTest.class.getSimpleName() + ".eml";
@Test
public void testPreloadMailFromFs() throws Exception {
@@ -34,7 +40,9 @@ public void testPreloadMailFromFs() throws Exception {
msg.setFrom("bar@localhost");
msg.setSubject("Hello");
msg.setText("Test message saved as eml (electronic mail format, aka internet message format)");
- try (FileOutputStream os = new FileOutputStream(EML_FILE_NAME)) {
+
+ final Path emlFile = Files.createTempDirectory("tmp").resolve(EML_FILE_NAME);
+ try (FileOutputStream os = new FileOutputStream(emlFile.toString())) {
msg.writeTo(os);
}
@@ -42,9 +50,9 @@ public void testPreloadMailFromFs() throws Exception {
final ImapHostManager imapHostManager = greenMail.getManagers().getImapHostManager();
final UserManager userManager = greenMail.getManagers().getUserManager();
final GreenMailUser user = userManager.createUser("foo@localhost", "foo-login", "secret");
- try (InputStream source = Files.newInputStream(Paths.get(EML_FILE_NAME))) {
+ try (InputStream source = Files.newInputStream(emlFile)) {
final MimeMessage loadedMsg = new MimeMessage(session, source);
- imapHostManager.getFolder(user, "INBOX").store(loadedMsg);
+ imapHostManager.getFolder(user, ImapConstants.INBOX_NAME).store(loadedMsg);
}
// Verify
diff --git a/greenmail-core/src/test/java/com/icegreen/greenmail/util/PreLoadEmailsTest.java b/greenmail-core/src/test/java/com/icegreen/greenmail/util/PreLoadEmailsTest.java
new file mode 100644
index 0000000000..9dc8a15200
--- /dev/null
+++ b/greenmail-core/src/test/java/com/icegreen/greenmail/util/PreLoadEmailsTest.java
@@ -0,0 +1,114 @@
+package com.icegreen.greenmail.util;
+
+import com.icegreen.greenmail.imap.ImapConstants;
+import com.icegreen.greenmail.imap.ImapServer;
+import com.icegreen.greenmail.junit.GreenMailRule;
+import com.icegreen.greenmail.store.FolderException;
+import com.icegreen.greenmail.user.GreenMailUser;
+import jakarta.mail.Folder;
+import jakarta.mail.Message;
+import jakarta.mail.MessagingException;
+import org.eclipse.angus.mail.imap.IMAPStore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PreLoadEmailsTest {
+ @Rule
+ public final GreenMailRule greenMail = new GreenMailRule(ServerSetupTest.SMTP_IMAP);
+
+ @Test
+ public void testPreloadFromDirectory() throws IOException, MessagingException, FolderException {
+ /* Expected structure:
+ preload
+ ├── bar@localhost
+ │ └── INBOX
+ │ └── test-5.eml
+ ├── foo-bar@localhost
+ │ └── INBOX # Auto-created
+ ├── drafts@localhost
+ | ├── Drafts
+ │ └── INBOX # Auto-created
+ └── foo@localhost
+ ├── Drafts
+ │ └── draft.eml
+ └── INBOX
+ ├── f1
+ │ ├── f2
+ │ │ ├── test-3.eml
+ │ │ └── test-4.eml
+ │ └── test-2.eml
+ └── test-1.eml
+ */
+ final GreenMailUser existingUser = greenMail.setUser("bar@localhost", "bar@localhost", "bar");
+ greenMail.loadEmails(FileSystems.getDefault().getPath("test-classes/preload"));
+ final ImapServer imap = greenMail.getImap();
+ try (IMAPStore store = imap.createStore()) {
+ store.connect("foo@localhost", "foo@localhost");
+
+ try (Folder inbox = store.getFolder(ImapConstants.INBOX_NAME)) {
+ inbox.open(Folder.READ_ONLY);
+ final Message[] messages = inbox.getMessages();
+ assertThat(messages).hasSize(1);
+ assertThat(messages[0].getSubject()).isEqualTo("test-1");
+
+ try (Folder f1 = inbox.getFolder("f1")) {
+ f1.open(Folder.READ_ONLY);
+ final Message[] f1Messages = f1.getMessages();
+ assertThat(f1Messages).hasSize(1);
+ assertThat(f1Messages[0].getSubject()).isEqualTo("test-2");
+
+ try (Folder f2 = f1.getFolder("f2")) {
+ f2.open(Folder.READ_ONLY);
+ final Message[] f2Messages = f2.getMessages();
+ assertThat(f2Messages).hasSize(2);
+ assertThat(f2Messages[0].getSubject()).isIn("test-3", "test-4");
+ }
+ }
+ }
+ try (Folder inbox = store.getFolder("Drafts")) {
+ inbox.open(Folder.READ_ONLY);
+ final Message[] messages = inbox.getMessages();
+ assertThat(messages).hasSize(1);
+ assertThat(messages[0].getSubject()).isEqualTo("Draft-1");
+ }
+ }
+
+ // Empty folder for user 'foo-bar'
+ try (IMAPStore store = imap.createStore()) {
+ store.connect("foo-bar@localhost", "foo-bar@localhost");
+ try (Folder inbox = store.getFolder(ImapConstants.INBOX_NAME)) {
+ inbox.open(Folder.READ_ONLY);
+ assertThat(inbox.getMessages()).isEmpty();
+ }
+ }
+
+ // Only Drafts folder
+ try (IMAPStore store = imap.createStore()) {
+ store.connect("drafts@localhost", "drafts@localhost");
+ try (Folder inbox = store.getFolder(ImapConstants.INBOX_NAME)) { // Auto-created
+ inbox.open(Folder.READ_ONLY);
+ assertThat(inbox.getMessages()).isEmpty();
+ }
+ try (Folder drafts = store.getFolder("Drafts")) { // From filesystem structure
+ drafts.open(Folder.READ_ONLY);
+ assertThat(drafts.getMessages()).isEmpty();
+ }
+ }
+
+ // Pre-created user 'bar'
+ try (IMAPStore store = imap.createStore()) {
+ store.connect(existingUser.getLogin(), existingUser.getPassword());
+ try (Folder inbox = store.getFolder(ImapConstants.INBOX_NAME)) {
+ inbox.open(Folder.READ_ONLY);
+ final Message[] messages = inbox.getMessages();
+ assertThat(messages).hasSize(1);
+ assertThat(messages[0].getSubject()).isEqualTo("test-5");
+ }
+ }
+ }
+}
diff --git a/greenmail-core/src/test/resources/preload/bar@localhost/INBOX/test-5.eml b/greenmail-core/src/test/resources/preload/bar@localhost/INBOX/test-5.eml
new file mode 100644
index 0000000000..7e8c95ae8c
--- /dev/null
+++ b/greenmail-core/src/test/resources/preload/bar@localhost/INBOX/test-5.eml
@@ -0,0 +1,10 @@
+Date: Sat, 16 Sep 2023 17:10:44 +0200 (CEST)
+From: bar@localhost
+To: foo@localhost
+Message-ID: <1882145060.266.1694877044545@127.0.0.1>
+Subject: test-5
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Test message saved as eml (electronic mail format, aka internet message format)
diff --git a/greenmail-core/src/test/resources/preload/foo-bar@localhost/.keepme b/greenmail-core/src/test/resources/preload/foo-bar@localhost/.keepme
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/greenmail-core/src/test/resources/preload/foo@localhost/Drafts/draft.eml b/greenmail-core/src/test/resources/preload/foo@localhost/Drafts/draft.eml
new file mode 100644
index 0000000000..ca8546fc2a
--- /dev/null
+++ b/greenmail-core/src/test/resources/preload/foo@localhost/Drafts/draft.eml
@@ -0,0 +1,10 @@
+Date: Sat, 16 Sep 2023 17:10:44 +0200 (CEST)
+From: foo@localhost
+To: bar@localhost
+Message-ID: <1882145060.266.1694877044545@127.0.0.1>
+Subject: Draft-1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Test message saved as eml (electronic mail format, aka internet message format)
diff --git a/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/f2/test-3.eml b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/f2/test-3.eml
new file mode 100644
index 0000000000..f811b059c7
--- /dev/null
+++ b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/f2/test-3.eml
@@ -0,0 +1,10 @@
+Date: Sat, 16 Sep 2023 17:10:44 +0200 (CEST)
+From: bar@localhost
+To: foo@localhost
+Message-ID: <1882145060.266.1694877044545@127.0.0.1>
+Subject: test-3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Test message saved as eml (electronic mail format, aka internet message format)
diff --git a/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/f2/test-4.eml b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/f2/test-4.eml
new file mode 100644
index 0000000000..ffcfc2b81a
--- /dev/null
+++ b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/f2/test-4.eml
@@ -0,0 +1,10 @@
+Date: Sat, 16 Sep 2023 17:10:44 +0200 (CEST)
+From: bar@localhost
+To: foo@localhost
+Message-ID: <1882145060.266.1694877044545@127.0.0.1>
+Subject: test-4
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Test message saved as eml (electronic mail format, aka internet message format)
diff --git a/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/test-2.eml b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/test-2.eml
new file mode 100644
index 0000000000..fcc481a57d
--- /dev/null
+++ b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/f1/test-2.eml
@@ -0,0 +1,10 @@
+Date: Sat, 16 Sep 2023 17:10:44 +0200 (CEST)
+From: bar@localhost
+To: foo@localhost
+Message-ID: <1882145060.266.1694877044545@127.0.0.1>
+Subject: test-2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Test message saved as eml (electronic mail format, aka internet message format)
diff --git a/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/test-1.eml b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/test-1.eml
new file mode 100644
index 0000000000..8b957eed90
--- /dev/null
+++ b/greenmail-core/src/test/resources/preload/foo@localhost/INBOX/test-1.eml
@@ -0,0 +1,10 @@
+Date: Sat, 16 Sep 2023 17:10:44 +0200 (CEST)
+From: bar@localhost
+To: foo@localhost
+Message-ID: <1882145060.266.1694877044545@127.0.0.1>
+Subject: test-1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Test message saved as eml (electronic mail format, aka internet message format)