This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit e784cd945c9beff94776c6174bd6d9a6595e4013 Author: Benoit Tellier <[email protected]> AuthorDate: Sat Mar 21 11:01:36 2020 +0700 JAMES-3078 Migrate mock SMTP to reactor-netty --- server/mailet/mock-smtp-server/pom.xml | 8 +- .../mock/smtp/server/HTTPConfigurationServer.java | 186 ++++++++++++--------- .../mock/smtp/server/ConfigurationClientTest.java | 4 +- .../smtp/server/HTTPConfigurationServerTest.java | 19 +-- 4 files changed, 121 insertions(+), 96 deletions(-) diff --git a/server/mailet/mock-smtp-server/pom.xml b/server/mailet/mock-smtp-server/pom.xml index 14c00b3..2c59171 100644 --- a/server/mailet/mock-smtp-server/pom.xml +++ b/server/mailet/mock-smtp-server/pom.xml @@ -43,10 +43,6 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-jetty</artifactId> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> <artifactId>james-server-util</artifactId> </dependency> <dependency> @@ -86,6 +82,10 @@ <artifactId>feign-slf4j</artifactId> </dependency> <dependency> + <groupId>io.projectreactor.netty</groupId> + <artifactId>reactor-netty</artifactId> + </dependency> + <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> diff --git a/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/HTTPConfigurationServer.java b/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/HTTPConfigurationServer.java index 83f6ac0..32f7746 100644 --- a/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/HTTPConfigurationServer.java +++ b/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/HTTPConfigurationServer.java @@ -19,105 +19,78 @@ package org.apache.james.mock.smtp.server; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; -import static javax.servlet.http.HttpServletResponse.SC_OK; +import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; +import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST; +import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR; +import static io.netty.handler.codec.http.HttpResponseStatus.NO_CONTENT; +import static io.netty.handler.codec.http.HttpResponseStatus.OK; import java.io.IOException; +import java.util.Optional; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.james.http.jetty.Configuration; -import org.apache.james.http.jetty.JettyHttpServer; import org.apache.james.mock.smtp.server.jackson.MailAddressModule; import org.apache.james.mock.smtp.server.model.Mails; import org.apache.james.mock.smtp.server.model.MockSMTPBehaviorInformation; import org.apache.james.mock.smtp.server.model.MockSmtpBehaviors; import org.apache.james.util.Port; +import org.reactivestreams.Publisher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.guava.GuavaModule; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.github.steveash.guavate.Guavate; -public class HTTPConfigurationServer { - - public static class RunningStage { - private final HTTPConfigurationServer underlyingServer; - - private RunningStage(HTTPConfigurationServer underlyingServer) { - this.underlyingServer = underlyingServer; - } - - public Port getPort() { - return underlyingServer.getPort(); - } +import reactor.core.publisher.Mono; +import reactor.netty.DisposableServer; +import reactor.netty.http.server.HttpServer; +import reactor.netty.http.server.HttpServerRequest; +import reactor.netty.http.server.HttpServerResponse; - public void stop() throws Exception { - underlyingServer.stop(); - } - } +public class HTTPConfigurationServer { - static class SMTPBehaviorsServlet extends HttpServlet { - private final SMTPBehaviorRepository smtpBehaviorRepository; + public static final String APPLICATION_JSON = "application/json"; - SMTPBehaviorsServlet(SMTPBehaviorRepository smtpBehaviorRepository) { - this.smtpBehaviorRepository = smtpBehaviorRepository; + public static class Configuration { + static Configuration port(Port port) { + return new Configuration(Optional.of(port)); } - @Override - protected void doPut(HttpServletRequest req, HttpServletResponse resp) { - try { - MockSmtpBehaviors behaviors = OBJECT_MAPPER.readValue(req.getInputStream(), MockSmtpBehaviors.class); - smtpBehaviorRepository.setBehaviors(behaviors); - resp.setStatus(SC_NO_CONTENT); - } catch (IOException e) { - resp.setStatus(SC_BAD_REQUEST); - } + static Configuration randomPort() { + return new Configuration(Optional.empty()); } - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - MockSmtpBehaviors mockSmtpBehaviors = new MockSmtpBehaviors(smtpBehaviorRepository.remainingBehaviors() - .map(MockSMTPBehaviorInformation::getBehavior) - .collect(Guavate.toImmutableList())); + private final Optional<Port> port; - resp.setStatus(SC_OK); - resp.setContentType("application/json"); - OBJECT_MAPPER.writeValue(resp.getOutputStream(), mockSmtpBehaviors); + Configuration(Optional<Port> port) { + this.port = port; } - @Override - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) { - smtpBehaviorRepository.clearBehaviors(); - resp.setStatus(SC_NO_CONTENT); + Optional<Port> getPort() { + return port; } } - static class SMTPMailsServlet extends HttpServlet { - private final ReceivedMailRepository receivedMailRepository; + public static class RunningStage { + private final DisposableServer server; - SMTPMailsServlet(ReceivedMailRepository receivedMailRepository) { - this.receivedMailRepository = receivedMailRepository; + private RunningStage(DisposableServer server) { + this.server = server; } - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - Mails mails = new Mails(receivedMailRepository.list()); - resp.setStatus(SC_OK); - resp.setContentType("application/json"); - OBJECT_MAPPER.writeValue(resp.getOutputStream(), mails); + public Port getPort() { + return Port.of(server.port()); } - @Override - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) { - receivedMailRepository.clear(); - resp.setStatus(SC_NO_CONTENT); + public void stop() { + server.disposeNow(); } } + private static final Logger LOGGER = LoggerFactory.getLogger(HTTPConfigurationServer.class); + private static final int RANDOM_PORT = 0; static final String SMTP_BEHAVIORS = "/smtpBehaviors"; static final String SMTP_MAILS = "/smtpMails"; @@ -129,35 +102,88 @@ public class HTTPConfigurationServer { public static HTTPConfigurationServer onRandomPort(SMTPBehaviorRepository smtpBehaviorRepository, ReceivedMailRepository receivedMailRepository) { return new HTTPConfigurationServer(smtpBehaviorRepository, receivedMailRepository, - Configuration.builder().randomPort()); + Configuration.randomPort()); } public static HTTPConfigurationServer onPort(SMTPBehaviorRepository smtpBehaviorRepository, ReceivedMailRepository receivedMailRepository, Port port) { return new HTTPConfigurationServer(smtpBehaviorRepository, receivedMailRepository, - Configuration.builder().port(port.getValue())); + Configuration.port(port)); } - private final JettyHttpServer jettyHttpServer; + private final SMTPBehaviorRepository smtpBehaviorRepository; + private final ReceivedMailRepository receivedMailRepository; + private final Configuration configuration; + + private HTTPConfigurationServer(SMTPBehaviorRepository smtpBehaviorRepository, ReceivedMailRepository receivedMailRepository, Configuration configuration) { + this.smtpBehaviorRepository = smtpBehaviorRepository; + this.receivedMailRepository = receivedMailRepository; + this.configuration = configuration; + } - private HTTPConfigurationServer(SMTPBehaviorRepository smtpBehaviorRepository, ReceivedMailRepository receivedMailRepository, Configuration.Builder configurationBuilder) { - jettyHttpServer = JettyHttpServer.create(configurationBuilder.serve(SMTP_BEHAVIORS) - .with(new SMTPBehaviorsServlet(smtpBehaviorRepository)) - .serve(SMTP_MAILS) - .with(new SMTPMailsServlet(receivedMailRepository)) - .build()); + public RunningStage start() { + return new RunningStage(HttpServer.create() + .port(configuration.getPort() + .map(Port::getValue) + .orElse(RANDOM_PORT)) + .route(routes -> routes + .get(SMTP_BEHAVIORS, this::getBehaviors) + .put(SMTP_BEHAVIORS, this::putBehaviors) + .delete(SMTP_BEHAVIORS, this::deleteBehaviors) + .get(SMTP_MAILS, this::getMails) + .delete(SMTP_MAILS, this::deleteMails)) + .bindNow()); } - public RunningStage start() throws Exception { - jettyHttpServer.start(); - return new RunningStage(this); + private Publisher<Void> getBehaviors(HttpServerRequest req, HttpServerResponse res) { + MockSmtpBehaviors mockSmtpBehaviors = new MockSmtpBehaviors(smtpBehaviorRepository.remainingBehaviors() + .map(MockSMTPBehaviorInformation::getBehavior) + .collect(Guavate.toImmutableList())); + + try { + return res.status(OK) + .header(CONTENT_TYPE, APPLICATION_JSON) + .sendString(Mono.just(OBJECT_MAPPER.writeValueAsString(mockSmtpBehaviors))); + } catch (JsonProcessingException e) { + LOGGER.error("Could not serialize JSON", e); + return res.status(INTERNAL_SERVER_ERROR).send(); + } } - private Port getPort() { - return new Port(jettyHttpServer.getPort()); + private Publisher<Void> putBehaviors(HttpServerRequest req, HttpServerResponse res) { + return req.receive().aggregate().asInputStream() + .flatMap(inputStream -> { + try { + MockSmtpBehaviors behaviors = OBJECT_MAPPER.readValue(inputStream, MockSmtpBehaviors.class); + smtpBehaviorRepository.setBehaviors(behaviors); + return res.status(NO_CONTENT).send(); + } catch (IOException e) { + LOGGER.info("Bad request", e); + return res.status(BAD_REQUEST).send(); + } + }); } - private void stop() throws Exception { - jettyHttpServer.stop(); + private Publisher<Void> deleteBehaviors(HttpServerRequest req, HttpServerResponse res) { + smtpBehaviorRepository.clearBehaviors(); + return res.status(NO_CONTENT).send(); + } + + private Publisher<Void> deleteMails(HttpServerRequest req, HttpServerResponse res) { + receivedMailRepository.clear(); + return res.status(NO_CONTENT).send(); + } + + private Publisher<Void> getMails(HttpServerRequest req, HttpServerResponse res) { + Mails mails = new Mails(receivedMailRepository.list()); + + try { + return res.status(OK) + .header(CONTENT_TYPE, APPLICATION_JSON) + .sendString(Mono.just(OBJECT_MAPPER.writeValueAsString(mails))); + } catch (JsonProcessingException e) { + LOGGER.error("Could not serialize JSON", e); + return res.status(INTERNAL_SERVER_ERROR).send(); + } } } diff --git a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/ConfigurationClientTest.java b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/ConfigurationClientTest.java index c1d9c1f..ae1bdc3 100644 --- a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/ConfigurationClientTest.java +++ b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/ConfigurationClientTest.java @@ -34,7 +34,7 @@ class ConfigurationClientTest { private ReceivedMailRepository mailRepository; @BeforeEach - void setUp() throws Exception { + void setUp() { behaviorRepository = new SMTPBehaviorRepository(); mailRepository = new ReceivedMailRepository(); server = HTTPConfigurationServer.onRandomPort(behaviorRepository, mailRepository) @@ -44,7 +44,7 @@ class ConfigurationClientTest { } @AfterEach - void tearDown() throws Exception { + void tearDown() { server.stop(); } diff --git a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/HTTPConfigurationServerTest.java b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/HTTPConfigurationServerTest.java index 4cc18aa..962f1c8 100644 --- a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/HTTPConfigurationServerTest.java +++ b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/HTTPConfigurationServerTest.java @@ -24,8 +24,8 @@ import static io.restassured.RestAssured.when; import static io.restassured.RestAssured.with; import static io.restassured.config.EncoderConfig.encoderConfig; import static io.restassured.config.RestAssuredConfig.newConfig; -import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; +import static io.netty.handler.codec.http.HttpResponseStatus.NO_CONTENT; import static org.apache.james.mock.smtp.server.Fixture.JSON_BEHAVIORS; import static org.apache.james.mock.smtp.server.Fixture.JSON_MAIL; import static org.apache.james.mock.smtp.server.Fixture.JSON_MAILS_LIST; @@ -34,7 +34,6 @@ import static org.hamcrest.Matchers.hasSize; import java.nio.charset.StandardCharsets; import org.apache.james.mock.smtp.server.Fixture.MailsFixutre; -import org.eclipse.jetty.http.HttpStatus; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; @@ -52,7 +51,7 @@ class HTTPConfigurationServerTest { @Nested class SMTPBehaviorsTest { @BeforeEach - void setUp() throws Exception { + void setUp() { server = HTTPConfigurationServer.onRandomPort(new SMTPBehaviorRepository(), new ReceivedMailRepository()) .start(); @@ -66,7 +65,7 @@ class HTTPConfigurationServerTest { } @AfterEach - void tearDown() throws Exception { + void tearDown() { server.stop(); } @@ -115,7 +114,7 @@ class HTTPConfigurationServerTest { .when() .put() .then() - .statusCode(HttpStatus.NO_CONTENT_204); + .statusCode(NO_CONTENT.code()); } @Test @@ -127,7 +126,7 @@ class HTTPConfigurationServerTest { .when() .put() .then() - .statusCode(HttpStatus.NO_CONTENT_204); + .statusCode(NO_CONTENT.code()); } @Test @@ -135,7 +134,7 @@ class HTTPConfigurationServerTest { when() .delete() .then() - .statusCode(HttpStatus.NO_CONTENT_204); + .statusCode(NO_CONTENT.code()); } } @@ -144,7 +143,7 @@ class HTTPConfigurationServerTest { private ReceivedMailRepository mailRepository; @BeforeEach - void setUp() throws Exception { + void setUp() { mailRepository = new ReceivedMailRepository(); server = HTTPConfigurationServer.onRandomPort(new SMTPBehaviorRepository(), mailRepository) @@ -160,7 +159,7 @@ class HTTPConfigurationServerTest { } @AfterEach - void tearDown() throws Exception { + void tearDown() { server.stop(); } @@ -225,7 +224,7 @@ class HTTPConfigurationServerTest { when() .delete() .then() - .statusCode(SC_NO_CONTENT); + .statusCode(NO_CONTENT.code()); } @Test --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
