This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit eeff96fe3914133c0e4298d7de8eab24e178506d Author: Tung TRAN <[email protected]> AuthorDate: Mon Aug 2 17:12:58 2021 +0700 JAMES-3621 Mailbox webadmin routes - messageCount --- .../james/webadmin/routes/UserMailboxesRoutes.java | 42 ++++++++++ .../webadmin/service/UserMailboxesService.java | 6 ++ .../webadmin/routes/UserMailboxesRoutesTest.java | 96 ++++++++++++++++++++++ 3 files changed, 144 insertions(+) diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java index 781f6ed..ec25b8f 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java @@ -36,6 +36,7 @@ import javax.ws.rs.Produces; import org.apache.james.core.Username; import org.apache.james.mailbox.exception.MailboxNameException; +import org.apache.james.mailbox.exception.MailboxNotFoundException; import org.apache.james.mailbox.indexer.ReIndexer; import org.apache.james.task.TaskManager; import org.apache.james.webadmin.Constants; @@ -89,6 +90,7 @@ public class UserMailboxesRoutes implements Routes { public static final String USERS_BASE = "/users"; public static final String USER_MAILBOXES_BASE = USERS_BASE + Constants.SEPARATOR + USER_NAME + Constants.SEPARATOR + MAILBOXES; public static final String SPECIFIC_MAILBOX = USER_MAILBOXES_BASE + Constants.SEPARATOR + MAILBOX_NAME; + public static final String MESSAGE_COUNT_PATH = SPECIFIC_MAILBOX + "/messageCount"; private final UserMailboxesService userMailboxesService; private final JsonTransformer jsonTransformer; @@ -126,6 +128,8 @@ public class UserMailboxesRoutes implements Routes { defineDeleteUserMailboxes(); + messageCount(); + reIndexMailboxesRoute() .ifPresent(route -> service.post(USER_MAILBOXES_BASE, route, jsonTransformer)); } @@ -342,4 +346,42 @@ public class UserMailboxesRoutes implements Routes { } }); } + + @GET + @Path("/{mailboxName}/messageCount") + @ApiImplicitParams({ + @ApiImplicitParam(required = true, dataType = "string", name = "username", paramType = "path"), + @ApiImplicitParam(required = true, dataType = "string", name = "mailboxName", paramType = "path") + }) + @ApiOperation(value = "Counting emails in a given mailbox.") + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.OK_200, message = "The number emails in a given mailbox", response = String.class), + @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid mailbox name"), + @ApiResponse(code = HttpStatus.UNAUTHORIZED_401, message = "Unauthorized. The user is not authenticated on the platform"), + @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "Invalid get on user mailboxes"), + @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side.") + }) + public void messageCount() { + service.get(MESSAGE_COUNT_PATH, (request, response) -> { + try { + return userMailboxesService.messageCount(getUsernameParam(request), new MailboxName(request.params(MAILBOX_NAME))); + } catch (IllegalStateException | MailboxNotFoundException e) { + LOGGER.info("Invalid get on user mailbox", e); + throw ErrorResponder.builder() + .statusCode(HttpStatus.NOT_FOUND_404) + .type(ErrorType.NOT_FOUND) + .message("Invalid get on user mailboxes") + .cause(e) + .haltError(); + } catch (IllegalArgumentException | MailboxNameException e) { + LOGGER.info("Attempt to test existence of an invalid mailbox", e); + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorType.INVALID_ARGUMENT) + .message("Attempt to test existence of an invalid mailbox") + .cause(e) + .haltError(); + } + }); + } } diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java index 10f45c2..395bf71 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java @@ -108,6 +108,12 @@ public class UserMailboxesService { .forEach(Throwing.consumer(path -> deleteMailbox(mailboxSession, path))); } + public long messageCount(Username username, MailboxName mailboxName) throws UsersRepositoryException, MailboxException { + usernamePreconditions(username); + MailboxSession mailboxSession = mailboxManager.createSystemSession(username); + return mailboxManager.getMailbox(MailboxPath.forUser(username, mailboxName.asString()), mailboxSession).getMessageCount(mailboxSession); + } + private Stream<MailboxPath> listChildren(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxException { return listUserMailboxes(mailboxSession) .map(MailboxMetaData::getPath) diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java index 12f2a1d..0ecaefc 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java @@ -49,6 +49,7 @@ import java.time.ZonedDateTime; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.stream.IntStream; import javax.mail.Flags; @@ -102,6 +103,7 @@ import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex; import org.apache.james.task.Hostname; import org.apache.james.task.MemoryTaskManager; import org.apache.james.user.api.UsersRepository; +import org.apache.james.user.api.UsersRepositoryException; import org.apache.james.webadmin.WebAdminServer; import org.apache.james.webadmin.WebAdminUtils; import org.apache.james.webadmin.dto.WebAdminUserReindexingTaskAdditionalInformationDTO; @@ -119,6 +121,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -128,6 +132,8 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; class UserMailboxesRoutesTest { + private static final Logger LOGGER = LoggerFactory.getLogger(UserMailboxesRoutesTest.class); + public static MailboxMetaData testMetadata(MailboxPath path, MailboxId mailboxId, char delimiter) { return new MailboxMetaData(path, mailboxId, delimiter, MailboxMetaData.Children.CHILDREN_ALLOWED_BUT_UNKNOWN, MailboxMetaData.Selectability.NONE, new MailboxACL(), MailboxCounters.empty(mailboxId)); @@ -180,6 +186,8 @@ class UserMailboxesRoutesTest { @Nested class NormalBehaviour { + private MailboxManager mailboxManager; + @BeforeEach void setUp() throws Exception { InMemoryMailboxManager mailboxManager = InMemoryIntegrationResources.defaultResources().getMailboxManager(); @@ -188,6 +196,7 @@ class UserMailboxesRoutesTest { Mockito.when(searchIndex.deleteAll(any(), any())).thenReturn(Mono.empty()); createServer(mailboxManager, mailboxManager.getMapperFactory(), new InMemoryId.Factory(), searchIndex); + this.mailboxManager = mailboxManager; } @Test @@ -882,6 +891,93 @@ class UserMailboxesRoutesTest { .containsKeys("mailboxId") .containsEntry("mailboxName", MAILBOX_NAME)); } + + @Test + void getMessageCountShouldReturnZeroWhenMailBoxEmpty() { + with() + .put(MAILBOX_NAME); + + String response = when() + .get(MAILBOX_NAME + "/messageCount") + .then() + .statusCode(OK_200) + .extract() + .body().asString(); + + assertThat(response) + .isEqualTo("0"); + } + + @Test + void getMessageCountShouldReturnTotalEmailsInMailBox() { + with() + .put(MAILBOX_NAME); + + MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, MAILBOX_NAME); + MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); + + IntStream.range(0, 10) + .forEach(index -> { + try { + mailboxManager.getMailbox(mailboxPath, systemSession) + .appendMessage( + MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"), + systemSession); + } catch (MailboxException e) { + LOGGER.warn("Error when append message " + e); + } + }); + + String response = when() + .get(MAILBOX_NAME + "/messageCount") + .then() + .statusCode(OK_200) + .extract() + .body().asString(); + + assertThat(response) + .isEqualTo("10"); + } + + @Test + void getMessageCountShouldReturnErrorWhenUserIsNotFound() throws UsersRepositoryException { + when(usersRepository.contains(USERNAME)).thenReturn(false); + + Map<String, Object> errors = when() + .get(MAILBOX_NAME + "/messageCount") + .then() + .statusCode(NOT_FOUND_404) + .contentType(JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", NOT_FOUND_404) + .containsEntry("type", ERROR_TYPE_NOTFOUND) + .containsEntry("message", "Invalid get on user mailboxes") + .containsEntry("details", "User does not exist"); + } + + @Test + void getMessageCountShouldReturnErrorWhenMailboxDoesNotExist() { + Map<String, Object> errors = when() + .get(MAILBOX_NAME + "/messageCount") + .then() + .statusCode(NOT_FOUND_404) + .contentType(JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", NOT_FOUND_404) + .containsEntry("type", ERROR_TYPE_NOTFOUND) + .containsEntry("message", "Invalid get on user mailboxes") + .containsEntry("details", String.format("#private:%s:%s can not be found", USERNAME.asString(), MAILBOX_NAME)); + } } @Nested --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
