diff --git a/supplier/mail-supplier/pom.xml b/supplier/mail-supplier/pom.xml
index 143901f9..5ee72725 100644
--- a/supplier/mail-supplier/pom.xml
+++ b/supplier/mail-supplier/pom.xml
@@ -28,9 +28,25 @@
${jakarta-mail.version}
- com.sun.mail
+ org.eclipse.angus
jakarta.mail
- [2.0.1,)
+ 1.0.0
+
+
+ com.icegreen
+ greenmail-junit5
+ 2.0.0-alpha-3
+ test
+
+
+ com.sun.mail
+ jakarta.mail
+
+
+ jakarta.activation
+ jakarta.activation-api
+
+
diff --git a/supplier/mail-supplier/src/main/java/org/springframework/cloud/fn/supplier/mail/MailSupplierConfiguration.java b/supplier/mail-supplier/src/main/java/org/springframework/cloud/fn/supplier/mail/MailSupplierConfiguration.java
index 00da10b3..35ba4e82 100644
--- a/supplier/mail-supplier/src/main/java/org/springframework/cloud/fn/supplier/mail/MailSupplierConfiguration.java
+++ b/supplier/mail-supplier/src/main/java/org/springframework/cloud/fn/supplier/mail/MailSupplierConfiguration.java
@@ -25,14 +25,13 @@ import jakarta.mail.URLName;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.fn.common.config.ComponentCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.core.MessageSource;
-import org.springframework.integration.dsl.IntegrationFlows;
+import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.MessageProducerSpec;
import org.springframework.integration.dsl.MessageSourceSpec;
import org.springframework.integration.endpoint.MessageProducerSupport;
@@ -53,18 +52,23 @@ import org.springframework.messaging.Message;
* @author Artem Bilan
* @author Chris Schaefer
* @author Soby Chacko
+ * @author Corneil du Plessis
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(MailSupplierProperties.class)
public class MailSupplierConfiguration {
- @Autowired
- private MailSupplierProperties properties;
+
+ final private MailSupplierProperties properties;
+
+ public MailSupplierConfiguration(MailSupplierProperties properties) {
+ this.properties = properties;
+ }
@Bean
public Publisher> mailInboundFlow(MessageProducerSupport messageProducer) {
- return IntegrationFlows.from(messageProducer)
+ return IntegrationFlow.from(messageProducer)
.transform(Mail.toStringTransformer(this.properties.getCharset()))
.enrichHeaders(h -> h
.defaultOverwrite(true)
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/AbstractMailSupplierTests.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/AbstractMailSupplierTests.java
index 617dfced..08ef475a 100644
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/AbstractMailSupplierTests.java
+++ b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/AbstractMailSupplierTests.java
@@ -18,10 +18,15 @@ package org.springframework.cloud.fn.supplier.mail;
import java.util.function.Supplier;
+import com.icegreen.greenmail.user.GreenMailUser;
+import com.icegreen.greenmail.util.GreenMail;
+import com.icegreen.greenmail.util.GreenMailUtil;
+import com.icegreen.greenmail.util.ServerSetup;
+import com.icegreen.greenmail.util.ServerSetupTest;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import reactor.core.publisher.Flux;
import org.springframework.beans.factory.annotation.Autowired;
@@ -32,35 +37,44 @@ import org.springframework.integration.test.context.SpringIntegrationTest;
import org.springframework.messaging.Message;
import org.springframework.test.annotation.DirtiesContext;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@Disabled // TODO add test container solution
@SpringIntegrationTest(noAutoStartup = "*")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = {
- "mail.supplier.mark-as-read=true",
- "mail.supplier.delete=false",
- "mail.supplier.user-flag=testSIUserFlag",
- "mail.supplier.java-mail-properties=mail.imap.socketFactory.fallback=true\\n mail.store.protocol=imap\\n mail.debug=true" })
+ "mail.supplier.mark-as-read=true",
+ "mail.supplier.delete=false",
+ "mail.supplier.user-flag=testSIUserFlag",
+ "mail.supplier.java-mail-properties=mail.imap.socketFactory.fallback=true\\n mail.store.protocol=imap\\n mail.debug=true"})
@DirtiesContext
-public class AbstractMailSupplierTests {
+public abstract class AbstractMailSupplierTests {
+ protected static GreenMail mailServer;
- private static TestMailServer.MailServer MAIL_SERVER;
+ protected static GreenMailUser mailUser;
@Autowired
protected Supplier>> mailSupplier;
-
@Autowired
- private StandardIntegrationFlow integrationFlow;
+ protected StandardIntegrationFlow integrationFlow;
+ protected void sendMessage(String subject, String body) {
+ mailUser.deliver(GreenMailUtil.createTextEmail("bar@bax", "test@test", subject, body, mailServer.getSmtp().getServerSetup()));
+ }
- protected static void startMailServer(TestMailServer.MailServer mailServer)
- throws InterruptedException {
- MAIL_SERVER = mailServer;
- System.setProperty("test.mail.server.port", "" + MAIL_SERVER.getPort());
- int n = 0;
- while (n++ < 100 && (!MAIL_SERVER.isListening())) {
- Thread.sleep(100);
- }
- assertThat(n < 100).isTrue();
+ @BeforeAll
+ public static void setup() {
+ ServerSetup imap = ServerSetupTest.IMAP.dynamicPort();
+ imap.setServerStartupTimeout(10000);
+ ServerSetup pop3 = ServerSetupTest.POP3.dynamicPort();
+ pop3.setServerStartupTimeout(10000);
+ ServerSetup smtp = ServerSetupTest.SMTP.dynamicPort();
+ smtp.setServerStartupTimeout(10000);
+
+ mailServer = new GreenMail(new ServerSetup[]{imap, pop3, smtp});
+ mailUser = mailServer.setUser("user", "pw");
+ mailServer.start();
+ String imapPort = Integer.toString(mailServer.getImap().getServerSetup().getPort());
+ String pop3Port = Integer.toString(mailServer.getPop3().getServerSetup().getPort());
+ String smtpPort = Integer.toString(mailServer.getPop3().getServerSetup().getPort());
+ System.setProperty("test.mail.server.imap.port", imapPort);
+ System.setProperty("test.mail.server.pop3.port", pop3Port);
+ System.setProperty("test.mail.server.smtp.port", smtpPort);
}
@BeforeEach
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapFailTests.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapFailTests.java
index 0a27c049..63b89f1a 100644
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapFailTests.java
+++ b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapFailTests.java
@@ -16,8 +16,6 @@
package org.springframework.cloud.fn.supplier.mail;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
@@ -30,34 +28,29 @@ import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
-@Disabled // TODO add test container based solution
@TestPropertySource(properties = {
- "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.port}/INBOX",
- "mail.supplier.charset=cp1251"})
+ "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.imap.port}/INBOX",
+ "mail.supplier.charset=cp1251"})
public class ImapFailTests extends AbstractMailSupplierTests {
@Autowired
- MailToStringTransformer mailToStringTransformer;
+ protected MailToStringTransformer mailToStringTransformer;
- @BeforeAll
- public static void startImapServer() throws Throwable {
- startMailServer(TestMailServer.imap(0));
- }
@Test
- public void testSimpleTest() throws Exception {
-
- assertThat(TestUtils.getPropertyValue(mailToStringTransformer, "charset").equals("cp1251")).isTrue();
-
+ public void testSimpleTest() {
+ // given
+ sendMessage("test", "foo");
+ // when
final Flux> messageFlux = mailSupplier.get();
-
+ // then
+ assertThat(TestUtils.getPropertyValue(mailToStringTransformer, "charset").equals("cp1251")).isTrue();
StepVerifier.create(messageFlux)
- .assertNext((message) -> {
- assertThat(((String) message.getPayload()).equals("Test Mail")).isFalse();
- }
- )
- .thenCancel()
- .verify();
-
+ .assertNext((message) -> {
+ assertThat(((String) message.getPayload())).isNotEqualTo("Test Mail");
+ }
+ )
+ .thenCancel()
+ .verify();
}
}
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdleFailTests.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdleFailTests.java
index 144300f9..001f041e 100644
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdleFailTests.java
+++ b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdleFailTests.java
@@ -16,8 +16,6 @@
package org.springframework.cloud.fn.supplier.mail;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
@@ -27,29 +25,23 @@ import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
-@Disabled // TODO add test container based solution
@TestPropertySource(properties = {
- "mail.supplier.idle-imap=true",
- "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.port}/INBOX"})
+ "mail.supplier.idle-imap=true",
+ "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.imap.port}/INBOX"})
public class ImapIdleFailTests extends AbstractMailSupplierTests {
-
-
- @BeforeAll
- public static void startImapServer() throws Throwable {
- startMailServer(TestMailServer.imap(0));
- }
-
@Test
- public void testSimpleTest() throws Exception {
-
+ public void testSimpleTest() {
+ // given
+ sendMessage("test", "foo");
+ // when
final Flux> messageFlux = mailSupplier.get();
-
+ // then
StepVerifier.create(messageFlux)
- .assertNext((message) -> {
- assertThat(((String) message.getPayload()).equals("Test Mail")).isFalse();
- }
- )
- .thenCancel()
- .verify();
+ .assertNext((message) -> {
+ assertThat(((String) message.getPayload())).isNotEqualTo("Test Mail");
+ }
+ )
+ .thenCancel()
+ .verify();
}
}
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdlePassTests.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdlePassTests.java
index dd25e4da..1ed7aec3 100644
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdlePassTests.java
+++ b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapIdlePassTests.java
@@ -16,8 +16,6 @@
package org.springframework.cloud.fn.supplier.mail;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
@@ -27,28 +25,25 @@ import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
-@Disabled // TODO add test container based solution
@TestPropertySource(properties = {
- "mail.supplier.idle-imap=true",
- "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.port}/INBOX"})
+ "mail.supplier.idle-imap=true",
+ "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.imap.port}/INBOX"})
public class ImapIdlePassTests extends AbstractMailSupplierTests {
- @BeforeAll
- public static void startImapServer() throws Throwable {
- startMailServer(TestMailServer.imap(0));
- }
-
@Test
- public void testSimpleTest() throws Exception {
-
+ public void testSimpleTest() {
+ // given
+ sendMessage("test", "foo");
+ // when
final Flux> messageFlux = mailSupplier.get();
-
+ // then
StepVerifier.create(messageFlux)
- .assertNext((message) -> {
- assertThat(((String) message.getPayload()).endsWith("\r\n\r\nfoo\r\n\r\n"));
- }
- )
- .thenCancel()
- .verify();
+ .assertNext((message) -> {
+ System.out.println("Message:" + message);
+ assertThat(((String) message.getPayload())).isEqualTo("foo");
+ }
+ )
+ .thenCancel()
+ .verify();
}
}
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapPassTests.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapPassTests.java
index bacc200a..97cc2a3f 100644
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapPassTests.java
+++ b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/ImapPassTests.java
@@ -16,10 +16,13 @@
package org.springframework.cloud.fn.supplier.mail;
+import java.io.UnsupportedEncodingException;
import java.util.List;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
+import com.icegreen.greenmail.util.GreenMailUtil;
+import jakarta.mail.MessagingException;
+import jakarta.mail.internet.InternetAddress;
+import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
@@ -31,33 +34,34 @@ import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
-@Disabled // TODO add test container based solution
-@TestPropertySource(properties = "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.port}/INBOX")
+@TestPropertySource(properties = "mail.supplier.url=imap://user:pw@localhost:${test.mail.server.imap.port}/INBOX")
public class ImapPassTests extends AbstractMailSupplierTests {
- @BeforeAll
- public static void startImapServer() throws Throwable {
- startMailServer(TestMailServer.imap(0));
- }
@Test
- public void testSimpleTest() {
-
+ public void testSimpleTest() throws UnsupportedEncodingException, MessagingException {
+ // given
+ MimeMessage mailMessage = GreenMailUtil.createTextEmail("bar@foo", "test@test", "test", "foo", mailServer.getSmtp().getServerSetup());
+ mailMessage.addRecipients(jakarta.mail.Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("foo@bar", "Foo")});
+ mailMessage.addRecipients(jakarta.mail.Message.RecipientType.CC, new InternetAddress[]{new InternetAddress("a@b"), new InternetAddress("c@d")});
+ mailMessage.addRecipients(jakarta.mail.Message.RecipientType.BCC, new InternetAddress[]{new InternetAddress("e@f"), new InternetAddress("g@h")});
+ mailUser.deliver(mailMessage);
+ // when
final Flux> messageFlux = mailSupplier.get();
-
+ // then
StepVerifier.create(messageFlux)
- .assertNext((message) -> {
- assertThat(((String) message.getPayload()).endsWith("\r\n\r\nfoo\r\n\r\n"));
- MessageHeaders headers = message.getHeaders();
- assertThat(headers.get(MailHeaders.TO)).isInstanceOf(List.class);
- assertThat(headers.get(MailHeaders.CC)).isInstanceOf(List.class);
- assertThat(headers.get(MailHeaders.BCC)).isInstanceOf(List.class);
- assertThat(headers.get(MailHeaders.TO).toString()).isEqualTo("[Foo ]");
- assertThat(headers.get(MailHeaders.CC).toString()).isEqualTo("[a@b, c@d]");
- assertThat(headers.get(MailHeaders.BCC).toString()).isEqualTo("[e@f, g@h]");
- }
- )
- .thenCancel()
- .verify();
+ .assertNext((message) -> {
+ assertThat(((String) message.getPayload())).isEqualTo("foo");
+ MessageHeaders headers = message.getHeaders();
+ assertThat(headers.get(MailHeaders.TO)).isInstanceOf(List.class);
+ assertThat(headers.get(MailHeaders.CC)).isInstanceOf(List.class);
+ assertThat(headers.get(MailHeaders.BCC)).isInstanceOf(List.class);
+ assertThat(headers.get(MailHeaders.TO).toString()).isEqualTo("[bar@foo, Foo ]");
+ assertThat(headers.get(MailHeaders.CC).toString()).isEqualTo("[a@b, c@d]");
+ assertThat(headers.get(MailHeaders.BCC).toString()).isEqualTo("[e@f, g@h]");
+ }
+ )
+ .thenCancel()
+ .verify();
}
}
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3FailTests.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3FailTests.java
index 8ec32fdd..52a17c88 100644
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3FailTests.java
+++ b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3FailTests.java
@@ -16,8 +16,6 @@
package org.springframework.cloud.fn.supplier.mail;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
@@ -27,27 +25,24 @@ import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
-@Disabled // TODO add test container based solution
-@TestPropertySource(properties = "mail.supplier.url=pop3://user:pw@localhost:${test.mail.server.port}/INBOX")
+@TestPropertySource(properties = "mail.supplier.url=pop3://user:pw@localhost:${test.mail.server.pop3.port}/INBOX")
public class Pop3FailTests extends AbstractMailSupplierTests {
- @BeforeAll
- public static void startImapServer() throws Throwable {
- startMailServer(TestMailServer.pop3(0));
- }
@Test
- public void testSimpleTest() throws Exception {
-
+ public void testSimpleTest() {
+ // given
+ sendMessage("test", "foo");
+ // when
final Flux> messageFlux = mailSupplier.get();
-
+ // then
StepVerifier.create(messageFlux)
- .assertNext((message) -> {
- assertThat(((String) message.getPayload()).equals("Test Mail")).isFalse();
- }
- )
- .thenCancel()
- .verify();
+ .assertNext((message) -> {
+ assertThat(((String) message.getPayload())).isNotEqualTo("Test Mail");
+ }
+ )
+ .thenCancel()
+ .verify();
}
}
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3PassTests.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3PassTests.java
index 0b465d38..fb1166d7 100644
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3PassTests.java
+++ b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/Pop3PassTests.java
@@ -16,8 +16,6 @@
package org.springframework.cloud.fn.supplier.mail;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
@@ -27,26 +25,23 @@ import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
-@Disabled // TODO add test container based solution
-@TestPropertySource(properties = "mail.supplier.url=pop3://user:pw@localhost:${test.mail.server.port}/INBOX")
+@TestPropertySource(properties = "mail.supplier.url=pop3://user:pw@localhost:${test.mail.server.pop3.port}/INBOX")
public class Pop3PassTests extends AbstractMailSupplierTests {
- @BeforeAll
- public static void startImapServer() throws Throwable {
- startMailServer(TestMailServer.pop3(0));
- }
@Test
- public void testSimpleTest() throws Exception {
+ public void testSimpleTest() {
+ // given
+ sendMessage("test", "foo");
final Flux> messageFlux = mailSupplier.get();
StepVerifier.create(messageFlux)
- .assertNext((message) -> {
- assertThat(((String) message.getPayload()).endsWith("foo\r\n\r\n"));
- }
- )
- .thenCancel()
- .verify();
+ .assertNext((message) -> {
+ assertThat(((String) message.getPayload())).contains("foo");
+ }
+ )
+ .thenCancel()
+ .verify();
}
}
diff --git a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/TestMailServer.java b/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/TestMailServer.java
deleted file mode 100644
index 44b1c257..00000000
--- a/supplier/mail-supplier/src/test/java/org/springframework/cloud/fn/supplier/mail/TestMailServer.java
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * Copyright 2014-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.fn.supplier.mail;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.net.ServerSocketFactory;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.util.Base64Utils;
-
-/**
- * A basic test mail server for pop3, imap,
- * Serves up a canned email message with each protocol.
- * For smtp, it handles the basic handshaking and captures
- * the pertinent data so it can be verified by a test case.
- *
- * @author Gary Russell
- * @author Artem Bilan
- *
- * @since 5.0
- *
- * @deprecated since 5.5 in favor of GreenMail library for mail testing.
- *
- */
-@Deprecated
-public final class TestMailServer {
-
- private TestMailServer() {
- }
-
- public static SmtpServer smtp(int port) {
- try {
- return new SmtpServer(port);
- }
- catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- public static Pop3Server pop3(int port) {
- try {
- return new Pop3Server(port);
- }
- catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- public static ImapServer imap(int port) {
- try {
- return new ImapServer(port);
- }
- catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- public static class SmtpServer extends MailServer {
-
- SmtpServer(int port) throws IOException {
- super(port);
- }
-
- @Override
- protected MailHandler mailHandler(Socket socket) {
- return new SmtpHandler(socket);
- }
-
- class SmtpHandler extends MailHandler {
-
- SmtpHandler(Socket socket) {
- super(socket);
- }
-
- @Override // NOSONAR
- void doRun() { // NOSONAR
- try {
- write("220 foo SMTP");
- while (!socket.isClosed()) {
- String line = reader.readLine();
- if (line == null) {
- break;
- }
- if (line.contains("EHLO")) {
- write("250-foo hello [0,0,0,0], foo");
- write("250-AUTH LOGIN PLAIN");
- write("250 OK");
- }
- else if (line.contains("MAIL FROM")) {
- write("250 OK");
- }
- else if (line.contains("RCPT TO")) {
- write("250 OK");
- }
- else if (line.contains("AUTH LOGIN")) {
- write("334 VXNlcm5hbWU6");
- }
- else if (line.contains("dXNlcg==")) { // base64 'user'
- sb.append("user:");
- sb.append((new String(Base64Utils.decode(line.getBytes()))));
- sb.append("\n");
- write("334 UGFzc3dvcmQ6");
- }
- else if (line.contains("cHc=")) { // base64 'pw'
- sb.append("password:");
- sb.append((new String(Base64Utils.decode(line.getBytes()))));
- sb.append("\n");
- write("235");
- }
- else if (line.equals("DATA")) {
- write("354");
- }
- else if (line.equals(".")) {
- write("250");
- }
- else if (line.equals("QUIT")) {
- write("221");
- socket.close();
- }
- else {
- sb.append(line);
- sb.append("\n");
- }
- }
- messages.add(sb.toString());
- }
- catch (IOException e) {
- if (!this.stopped) {
- LOGGER.error(IO_EXCEPTION, e);
- }
- }
- }
-
- }
-
- }
-
- public static class Pop3Server extends MailServer {
-
- Pop3Server(int port) throws IOException {
- super(port);
- }
-
- @Override
- protected MailHandler mailHandler(Socket socket) {
- return new Pop3Handler(socket);
- }
-
- class Pop3Handler extends MailHandler {
-
- private static final String PLUS_OK = "+OK";
-
- Pop3Handler(Socket socket) {
- super(socket);
- }
-
- @Override // NOSONAR
- void doRun() {
- try {
- write("+OK POP3");
- while (!socket.isClosed()) {
- String line = reader.readLine();
- if (line == null) {
- break;
- }
- switch (line) {
- case "CAPA":
- write(PLUS_OK);
- write("USER");
- write(".");
- break;
- case "USER user":
- case "PASS pw":
- case "NOOP":
- write(PLUS_OK);
- break;
- case "STAT":
- write("+OK 1 3");
- break;
- case "RETR 1":
- write(PLUS_OK);
- write(MESSAGE);
- write(".");
- break;
- case "QUIT":
- write(PLUS_OK);
- socket.close();
- break;
- default:
- throw new UnsupportedOperationException(line);
- }
- }
- }
- catch (IOException e) {
- if (!this.stopped) {
- LOGGER.error(IO_EXCEPTION, e);
- }
- }
- }
-
- }
-
- }
-
- public static class ImapServer extends MailServer {
-
- private volatile boolean seen;
-
- private volatile boolean idled;
-
- ImapServer(int port) throws IOException {
- super(port);
- }
-
- @Override
- public void resetServer() {
- super.resetServer();
- this.seen = false;
- this.idled = false;
- }
-
- @Override
- protected MailHandler mailHandler(Socket socket) {
- return new ImapHandler(socket);
- }
-
- class ImapHandler extends MailHandler {
-
- private static final String OK_FETCH_COMPLETED = "OK FETCH completed";
-
- /**
- * Time to wait while IDLE before returning a result.
- */
- private static final int IDLE_WAIT_TIME = 500;
-
- ImapHandler(Socket socket) {
- super(socket);
- }
-
- @Override // NOSONAR
- void doRun() {
- try {
- write("* OK IMAP4rev1 Service Ready");
- String idleTag = "";
- while (!socket.isClosed()) {
- String line = reader.readLine();
- if (line == null) {
- break;
- }
- String tag = line.substring(0, line.indexOf(' ') + 1);
- if (line.endsWith("CAPABILITY")) {
- write("* CAPABILITY IDLE IMAP4rev1");
- write(tag + "OK CAPABILITY completed");
- }
- else if (line.endsWith("LOGIN user pw")) {
- write(tag + "OK LOGIN completed");
- }
- else if (line.endsWith("LIST \"\" INBOX")) {
- write("* LIST \"/\" \"INBOX\"");
- write(tag + "OK LIST completed");
- }
- else if (line.endsWith("LIST \"\" \"\"")) {
- write("* LIST \"/\" \"\"");
- write(tag + "OK LIST completed");
- }
- else if (line.endsWith("SELECT INBOX")) {
- write("* 1 EXISTS");
- if (!seen) {
- write("* 1 RECENT");
- write("* OK [UNSEEN 1]");
- }
- else {
- write("* OK");
- }
- write("* OK [PERMANENTFLAGS (\\Deleted \\Seen \\*)]"); // \* - user flags allowed
- write(tag + "OK SELECT completed");
- }
- else if (line.endsWith("EXAMINE INBOX")) {
- write(tag + "OK");
- }
- else if (line.endsWith("SEARCH FROM bar@baz UNSEEN ALL")) {
- searchReply(tag);
- }
- else if (line.endsWith("SEARCH NOT (DELETED) NOT (SEEN) NOT (KEYWORD testSIUserFlag) ALL")) {
- searchReply(tag);
- assertions.add("searchWithUserFlag");
- }
- else if (line.contains("FETCH 1 (ENVELOPE")) {
- write("* 1 FETCH (RFC822.SIZE "
- + MESSAGE.length()
- + " INTERNALDATE \"27-May-2013 09:45:41 +0000\" "
- + "FLAGS (\\Seen) "
- + "ENVELOPE (\"Mon, 27 May 2013 15:14:49 +0530\" "
- + "\"Test Email\" "
- + "((\"Bar\" NIL \"bar\" \"baz\")) " // From
- + "((\"Bar\" NIL \"bar\" \"baz\")) " // Sender
- + "((\"Bar\" NIL \"bar\" \"baz\")) " // Reply To
- + "((\"Foo\" NIL \"foo\" \"bar\")) " // To
- + "((NIL NIL \"a\" \"b\") (NIL NIL \"c\" \"d\")) " // cc
- + "((NIL NIL \"e\" \"f\") (NIL NIL \"g\" \"h\")) " // bcc
- + "\"<4DA0A7E4.3010506@baz.net>\" " // In reply to
- + "\"\") " // msgid
- + "BODYSTRUCTURE "
- + "(\"TEXT\" \"PLAIN\" (\"CHARSET\" \"ISO-8859-1\") NIL NIL \"7BIT\" 1 5)))");
- write(tag + OK_FETCH_COMPLETED);
- }
- else if (line.contains("FETCH 2 (BODYSTRUCTURE)")) {
- write("* 2 FETCH " +
- "BODYSTRUCTURE "
- + "(\"TEXT\" \"PLAIN\" (\"CHARSET\" \"ISO-8859-1\") NIL NIL \"7BIT\" 1 5)))");
- write(tag + OK_FETCH_COMPLETED);
- }
- else if (line.contains("STORE 1 +FLAGS (\\Flagged)")) {
- write("* 1 FETCH (FLAGS (\\Flagged))");
- write(tag + "OK STORE completed");
- }
- else if (line.contains("STORE 1 +FLAGS (\\Seen)")) {
- write("* 1 FETCH (FLAGS (\\Flagged \\Seen))");
- write(tag + "OK STORE completed");
- seen = true;
- }
- else if (line.contains("FETCH 1 FLAGS")) {
- write("* 1 FLAGS(\\Seen)");
- write(tag + OK_FETCH_COMPLETED);
- }
- else if (line.contains("FETCH 1 (BODY.PEEK")) {
- write("* 1 FETCH (BODY[]<0> {" + (MESSAGE.length() + 2) + "}");
- write(MESSAGE);
- write(")");
- write(tag + OK_FETCH_COMPLETED);
- }
- else if (line.contains("CLOSE")) {
- write(tag + "OK CLOSE completed");
- }
- else if (line.contains("NOOP")) {
- write(tag + "OK NOOP completed");
- }
- else if (line.endsWith("STORE 1 +FLAGS (testSIUserFlag)")) {
- write(tag + "OK STORE completed");
- assertions.add("storeUserFlag");
- }
- else if (line.endsWith("IDLE")) {
- write("+ idling");
- idleTag = tag;
- if (!idled) {
- try {
- Thread.sleep(IDLE_WAIT_TIME);
- write("* 2 EXISTS");
- seen = false;
- }
- catch (@SuppressWarnings("unused") InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- idled = true;
- }
- else if (line.equals("DONE")) {
- write(idleTag + "OK");
- }
- else if (line.contains("LOGOUT")) {
- write(tag + "OK LOGOUT completed");
- this.socket.close();
- }
- }
- }
- catch (IOException e) {
- if (!this.stopped) {
- LOGGER.error(IO_EXCEPTION, e);
- }
- }
- } // NOSONAR
-
- void searchReply(String tag) throws IOException {
- if (seen) {
- write("* SEARCH");
- }
- else {
- write("* SEARCH 1");
- }
- write(tag + "OK SEARCH completed");
- }
-
- }
-
- }
-
- public abstract static class MailServer implements Runnable {
-
- protected final Log LOGGER = LogFactory.getLog(getClass()); // NOSONAR
-
- protected static final String IO_EXCEPTION = "IOException"; // NOSONAR
-
- private final ServerSocket serverSocket;
-
- private final ExecutorService exec = Executors.newCachedThreadPool();
-
- protected final Set assertions = new HashSet<>(); // NOSONAR protected
-
- protected final List messages = new ArrayList<>(); // NOSONAR protected
-
- private final List handlers = new ArrayList<>();
-
- private volatile boolean listening;
-
- MailServer(int port) throws IOException {
- this.serverSocket = ServerSocketFactory.getDefault().createServerSocket(port);
- this.listening = true;
- exec.execute(this);
- }
-
- public int getPort() {
- return this.serverSocket.getLocalPort();
- }
-
- public boolean isListening() {
- return listening;
- }
-
- public List getMessages() {
- return messages;
- }
-
- public void resetServer() {
- this.assertions.clear();
- }
-
- public boolean assertReceived(String assertion) {
- return this.assertions.contains(assertion);
- }
-
- @Override
- public void run() {
- try {
- while (!serverSocket.isClosed()) {
- Socket socket = this.serverSocket.accept();
- MailHandler mailHandler = mailHandler(socket);
- this.handlers.add(mailHandler);
- exec.execute(mailHandler);
- }
- }
- catch (@SuppressWarnings("unused") IOException e) {
- this.listening = false;
- }
- }
-
- protected abstract MailHandler mailHandler(Socket socket);
-
- public void stop() {
- try {
- for (MailHandler handler : this.handlers) {
- handler.stop();
- }
- this.serverSocket.close();
- }
- catch (IOException e) {
- LOGGER.error(IO_EXCEPTION, e);
- }
- this.exec.shutdownNow();
- }
-
- public abstract class MailHandler implements Runnable {
-
- public static final String BODY = "foo\r\n";
-
- public static final String MESSAGE =
- "To: Foo \r\n"
- + "cc: a@b, c@d\r\n"
- + "bcc: e@f, g@h\r\n"
- + "From: Bar , Bar2 \r\n"
- + "Subject: Test Email\r\n"
- + "\r\n" + BODY;
-
- protected final Socket socket; // NOSONAR protected
-
- private BufferedWriter writer;
-
- protected StringBuilder sb = new StringBuilder(); // NOSONAR protected
-
- protected BufferedReader reader; // NOSONAR protected
-
- protected boolean stopped; // NOSONAR
-
- MailHandler(Socket socket) {
- this.socket = socket;
- }
-
- @Override
- public void run() {
- try {
- this.reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
- this.writer = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
- }
- catch (IOException e) {
- LOGGER.error(IO_EXCEPTION, e);
- }
- doRun();
- }
-
- protected void write(String str) throws IOException {
- this.writer.write(str);
- this.writer.write("\r\n");
- this.writer.flush();
- }
-
- abstract void doRun();
-
- void stop() {
- this.stopped = true;
- try {
- this.socket.close();
- }
- catch (IOException e) {
- // NOSONAR
- }
- }
-
- }
-
- }
-
-
-}