JAMES-2292 Limit the number of messages
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b9ee9077 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b9ee9077 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b9ee9077 Branch: refs/heads/master Commit: b9ee9077638b169839014602f7ff343aa5d3ef4f Parents: 60b743a Author: Antoine Duprat <[email protected]> Authored: Tue Jan 23 16:55:09 2018 +0100 Committer: benwa <[email protected]> Committed: Thu Jan 25 11:46:42 2018 +0700 ---------------------------------------------------------------------- .../james/webadmin/routes/MailQueueRoutes.java | 69 ++++++++++---- .../webadmin/routes/MailQueueRoutesTest.java | 96 +++++++++++++++----- .../routes/MailQueueRoutesUnitTest.java | 34 +++++++ 3 files changed, 158 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/b9ee9077/server/protocols/webadmin/webadmin-mailqueue/src/main/java/org/apache/james/webadmin/routes/MailQueueRoutes.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailqueue/src/main/java/org/apache/james/webadmin/routes/MailQueueRoutes.java b/server/protocols/webadmin/webadmin-mailqueue/src/main/java/org/apache/james/webadmin/routes/MailQueueRoutes.java index bcaee97..6e67340 100644 --- a/server/protocols/webadmin/webadmin-mailqueue/src/main/java/org/apache/james/webadmin/routes/MailQueueRoutes.java +++ b/server/protocols/webadmin/webadmin-mailqueue/src/main/java/org/apache/james/webadmin/routes/MailQueueRoutes.java @@ -33,6 +33,7 @@ import org.apache.james.queue.api.MailQueue.MailQueueException; import org.apache.james.queue.api.MailQueueFactory; import org.apache.james.queue.api.ManageableMailQueue; import org.apache.james.util.streams.Iterators; +import org.apache.james.util.streams.Limit; import org.apache.james.webadmin.Routes; import org.apache.james.webadmin.dto.MailQueueDTO; import org.apache.james.webadmin.dto.MailQueueItemDTO; @@ -40,8 +41,6 @@ import org.apache.james.webadmin.utils.ErrorResponder; import org.apache.james.webadmin.utils.ErrorResponder.ErrorType; import org.apache.james.webadmin.utils.JsonTransformer; import org.eclipse.jetty.http.HttpStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.github.fge.lambdas.Throwing; import com.github.steveash.guavate.Guavate; @@ -53,6 +52,7 @@ import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; +import spark.HaltException; import spark.Request; import spark.Service; @@ -64,12 +64,12 @@ public class MailQueueRoutes implements Routes { @VisibleForTesting static final String BASE_URL = "/mailQueues"; @VisibleForTesting static final String MAIL_QUEUE_NAME = ":mailQueueName"; - @VisibleForTesting static final String MESSAGES = "/messages"; + @VisibleForTesting static final String MAILS = "/mails"; private static final String DELAYED_QUERY_PARAM = "delayed"; + private static final String LIMIT_QUERY_PARAM = "limit"; + @VisibleForTesting static final int DEFAULT_LIMIT_VALUE = 100; - private static final Logger LOGGER = LoggerFactory.getLogger(MailQueueRoutes.class); - private final MailQueueFactory<ManageableMailQueue> mailQueueFactory; private final JsonTransformer jsonTransformer; @@ -85,7 +85,7 @@ public class MailQueueRoutes implements Routes { getMailQueue(service); - listMessages(service); + listMails(service); } @GET @@ -152,29 +152,44 @@ public class MailQueueRoutes implements Routes { } @GET - @Path("/{mailQueueName}/messages") + @Path("/{mailQueueName}/mails") @ApiImplicitParams({ @ApiImplicitParam(required = true, dataType = "string", name = "mailQueueName", paramType = "path"), - @ApiImplicitParam(required = false, dataType = "boolean", name = DELAYED_QUERY_PARAM, paramType = "query") + @ApiImplicitParam( + required = false, + dataType = "boolean", + name = DELAYED_QUERY_PARAM, + paramType = "query", + example = "?delayed=true", + value = "Whether the mails are delayed in the mail queue or not (already sent)."), + @ApiImplicitParam( + required = false, + dataType = "int", + name = LIMIT_QUERY_PARAM, + paramType = "query", + example = "?limit=100", + defaultValue = "100", + value = "Limits the maximum number of mails returned by this endpoint") }) @ApiOperation( - value = "List the messages of the MailQueue" + value = "List the mails of the MailQueue" ) @ApiResponses(value = { @ApiResponse(code = HttpStatus.OK_200, message = "OK", response = List.class), @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The MailQueue does not exist."), + @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid request for listing the mails from the mail queue."), @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side.") }) - public void listMessages(Service service) { - service.get(BASE_URL + SEPARATOR + MAIL_QUEUE_NAME + MESSAGES, - (request, response) -> listMessages(request), + public void listMails(Service service) { + service.get(BASE_URL + SEPARATOR + MAIL_QUEUE_NAME + MAILS, + (request, response) -> listMails(request), jsonTransformer); } - private List<MailQueueItemDTO> listMessages(Request request) { + private List<MailQueueItemDTO> listMails(Request request) { String mailQueueName = request.params(MAIL_QUEUE_NAME); return mailQueueFactory.getQueue(mailQueueName) - .map(name -> listMessages(name, isDelayed(request.queryParams(DELAYED_QUERY_PARAM)))) + .map(name -> listMails(name, isDelayed(request.queryParams(DELAYED_QUERY_PARAM)), limit(request.queryParams(LIMIT_QUERY_PARAM)))) .orElseThrow( () -> ErrorResponder.builder() .message(String.format("%s can not be found", mailQueueName)) @@ -188,25 +203,39 @@ public class MailQueueRoutes implements Routes { .map(Boolean::parseBoolean); } - private List<MailQueueItemDTO> listMessages(ManageableMailQueue queue, Optional<Boolean> isDelayed) { + @VisibleForTesting Limit limit(String limitAsString) throws HaltException { try { - return Iterators.toStream(queue.browse()) - .map(Throwing.function(MailQueueItemDTO::from)) + return Optional.ofNullable(limitAsString) + .map(Integer::parseInt) + .map(Limit::limit) + .orElseGet(() -> Limit.from(DEFAULT_LIMIT_VALUE)); + } catch (IllegalArgumentException e) { + throw ErrorResponder.builder() + .message(String.format("limit can't be less or equals to zero")) + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorResponder.ErrorType.NOT_FOUND) + .haltError(); + } + } + + private List<MailQueueItemDTO> listMails(ManageableMailQueue queue, Optional<Boolean> isDelayed, Limit limit) { + try { + return limit.applyOnStream(Iterators.toStream(queue.browse())) + .map(Throwing.function(MailQueueItemDTO::from).sneakyThrow()) .filter(item -> filter(item, isDelayed)) .collect(Guavate.toImmutableList()); } catch (MailQueueException e) { - LOGGER.info("Invalid request for getting the mail queue " + queue, e); throw ErrorResponder.builder() .statusCode(HttpStatus.BAD_REQUEST_400) .type(ErrorType.INVALID_ARGUMENT) - .message("Invalid request for getting the mail queue " + queue) + .message("Invalid request for listing the mails from the mail queue " + queue) .cause(e) .haltError(); } } private boolean filter(MailQueueItemDTO item, Optional<Boolean> isDelayed) { - return isDelayed.map(delayed -> delayed == item.isDelayed()) + return isDelayed.map(delayed -> delayed == item.getNextDelivery().isPresent()) .orElse(true); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/b9ee9077/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesTest.java b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesTest.java index 1e0f942..291c6b1 100644 --- a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesTest.java @@ -19,6 +19,7 @@ package org.apache.james.webadmin.routes; +import static com.jayway.restassured.RestAssured.given; import static com.jayway.restassured.RestAssured.when; import static com.jayway.restassured.config.EncoderConfig.encoderConfig; import static com.jayway.restassured.config.RestAssuredConfig.newConfig; @@ -170,11 +171,11 @@ public class MailQueueRoutesTest { } @Test - public void listMessagesShouldReturnEmptyListWhenNoMessages() { + public void listMailsShouldReturnEmptyListWhenNoMails() { mailQueueFactory.createQueue(FIRST_QUEUE); when() - .get(FIRST_QUEUE + "/messages") + .get(FIRST_QUEUE + "/mails") .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) @@ -182,13 +183,13 @@ public class MailQueueRoutesTest { } @Test - public void listMessagesShouldReturnMessagesWhenSome() throws Exception { + public void listMailsShouldReturnMailsWhenSome() throws Exception { MemoryMailQueue queue = mailQueueFactory.createQueue(FIRST_QUEUE); queue.enQueue(Mails.defaultMail().build()); queue.enQueue(Mails.defaultMail().build()); when() - .get(FIRST_QUEUE + "/messages") + .get(FIRST_QUEUE + "/mails") .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) @@ -196,38 +197,37 @@ public class MailQueueRoutesTest { } @Test - public void listMessagesShouldReturnMessageDetailWhenSome() throws Exception { + public void listMailsShouldReturnMailDetailsWhenSome() throws Exception { MemoryMailQueue queue = mailQueueFactory.createQueue(FIRST_QUEUE); FakeMail mail = Mails.defaultMail().build(); queue.enQueue(mail); - String firstMessage = "[0]"; + String firstMail = "[0]"; List<String> expectedRecipients = mail.getRecipients().stream() - .map(MailAddress::asPrettyString) + .map(MailAddress::asString) .collect(Guavate.toImmutableList()); when() - .get(FIRST_QUEUE + "/messages") + .get(FIRST_QUEUE + "/mails") .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) .body(".", hasSize(1)) - .body(firstMessage + ".name", equalTo(mail.getName())) - .body(firstMessage + ".sender", equalTo(mail.getSender().asPrettyString())) - .body(firstMessage + ".recipients", equalTo(expectedRecipients)) - .body(firstMessage + ".delayed", equalTo(false)); + .body(firstMail + ".name", equalTo(mail.getName())) + .body(firstMail + ".sender", equalTo(mail.getSender().asString())) + .body(firstMail + ".recipients", equalTo(expectedRecipients)); } @Test - public void listMessagesShouldReturnEmptyWhenNoDelayedMessagesAndAskFor() throws Exception { + public void listMailsShouldReturnEmptyWhenNoDelayedMailsAndAskFor() throws Exception { MemoryMailQueue queue = mailQueueFactory.createQueue(FIRST_QUEUE); FakeMail mail = Mails.defaultMail().build(); queue.enQueue(mail); - RestAssured.given() + given() .param("delayed", "true") .when() - .get(FIRST_QUEUE + "/messages") + .get(FIRST_QUEUE + "/mails") .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) @@ -235,15 +235,15 @@ public class MailQueueRoutesTest { } @Test - public void listMessagesShouldReturnCurrentMessagesWhenMessagesAndAskForNotDelayed() throws Exception { + public void listMailsShouldReturnCurrentMailsWhenMailsAndAskForNotDelayed() throws Exception { MemoryMailQueue queue = mailQueueFactory.createQueue(FIRST_QUEUE); FakeMail mail = Mails.defaultMail().build(); queue.enQueue(mail); - RestAssured.given() + given() .param("delayed", "false") .when() - .get(FIRST_QUEUE + "/messages") + .get(FIRST_QUEUE + "/mails") .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) @@ -252,18 +252,72 @@ public class MailQueueRoutesTest { @Ignore("MemoryMailQueueFactory doesn't support delay") @Test - public void listMessagesShouldReturnDelayedMessagesAndAskFor() throws Exception { + public void listMailsShouldReturnDelayedMailsWhenAskFor() throws Exception { MemoryMailQueue queue = mailQueueFactory.createQueue(FIRST_QUEUE); FakeMail mail = Mails.defaultMail().build(); queue.enQueue(mail, 10, TimeUnit.MINUTES); - RestAssured.given() + given() .param("delayed", "true") .when() - .get(FIRST_QUEUE + "/messages") + .get(FIRST_QUEUE + "/mails") .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) .body(".", hasSize(1)); } + + @Test + public void listMailsShouldReturnOneMailWhenMailsAndAskForALimitOfOne() throws Exception { + MemoryMailQueue queue = mailQueueFactory.createQueue(FIRST_QUEUE); + FakeMail mail = Mails.defaultMail().build(); + queue.enQueue(mail); + queue.enQueue(mail); + queue.enQueue(mail); + + given() + .param("limit", "1") + .when() + .get(FIRST_QUEUE + "/mails") + .then() + .statusCode(HttpStatus.OK_200) + .contentType(ContentType.JSON) + .body(".", hasSize(1)); + } + + @Test + public void listMailsShouldReturnBadRequestWhenLimitIsLessThanZero() throws Exception { + mailQueueFactory.createQueue(FIRST_QUEUE); + + given() + .param("limit", "-1") + .when() + .get(FIRST_QUEUE + "/mails") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400); + } + + @Test + public void listMailsShouldReturnBadRequestWhenLimitEqualsToZero() throws Exception { + mailQueueFactory.createQueue(FIRST_QUEUE); + + given() + .param("limit", "0") + .when() + .get(FIRST_QUEUE + "/mails") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400); + } + + @Test + public void listMailsShouldReturnBadRequestWhenLimitIsInvalid() throws Exception { + mailQueueFactory.createQueue(FIRST_QUEUE); + + given() + .param("limit", "abc") + .when() + .get(FIRST_QUEUE + "/mails") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/b9ee9077/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesUnitTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesUnitTest.java b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesUnitTest.java index 859f52e..16d534e 100644 --- a/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesUnitTest.java +++ b/server/protocols/webadmin/webadmin-mailqueue/src/test/java/org/apache/james/webadmin/routes/MailQueueRoutesUnitTest.java @@ -20,15 +20,19 @@ package org.apache.james.webadmin.routes; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.Optional; import org.apache.james.queue.api.MailQueueFactory; import org.apache.james.queue.api.ManageableMailQueue; +import org.apache.james.util.streams.Limit; import org.apache.james.webadmin.utils.JsonTransformer; import org.junit.Before; import org.junit.Test; +import spark.HaltException; + public class MailQueueRoutesUnitTest { MailQueueRoutes testee; @@ -62,4 +66,34 @@ public class MailQueueRoutesUnitTest { Optional<Boolean> delayed = testee.isDelayed("abc"); assertThat(delayed).contains(false); } + + @Test + public void limitShouldBeEqualsToDefaultValueWhenNull() { + Limit limit = testee.limit(null); + assertThat(limit.getLimit()).contains(MailQueueRoutes.DEFAULT_LIMIT_VALUE); + } + + @Test + public void limitShouldBeEqualsToTheValueWhenOne() { + Limit limit = testee.limit("123"); + assertThat(limit.getLimit()).contains(123); + } + + @Test + public void limitShouldThrowWhenOtherValue() { + assertThatThrownBy(() -> testee.limit("abc")) + .isInstanceOf(HaltException.class); + } + + @Test + public void limitShouldThrowWhenEqualsToZero() { + assertThatThrownBy(() -> testee.limit("0")) + .isInstanceOf(HaltException.class); + } + + @Test + public void limitShouldThrowWhenLessThanZero() { + assertThatThrownBy(() -> testee.limit("-1")) + .isInstanceOf(HaltException.class); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
