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 d5bab2ab6347eb42d5ed66436270f77a59f5442f
Author: Tung TRAN <[email protected]>
AuthorDate: Tue Aug 3 18:07:30 2021 +0700

    JAMES-3621 Mailbox webadmin - Clearing content of mailbox - Route
---
 .../WebadminMailboxTaskSerializationModule.java    |   8 +
 .../james/webadmin/routes/UserMailboxesRoutes.java |  43 +++++
 .../webadmin/service/UserMailboxesService.java     |  10 +-
 .../webadmin/routes/UserMailboxesRoutesTest.java   | 192 ++++++++++++++++++++-
 4 files changed, 251 insertions(+), 2 deletions(-)

diff --git 
a/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/WebadminMailboxTaskSerializationModule.java
 
b/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/WebadminMailboxTaskSerializationModule.java
index 369949d..e9010a2 100644
--- 
a/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/WebadminMailboxTaskSerializationModule.java
+++ 
b/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/WebadminMailboxTaskSerializationModule.java
@@ -30,6 +30,7 @@ import org.apache.james.server.task.json.dto.TaskDTOModule;
 import org.apache.james.task.Task;
 import org.apache.james.task.TaskExecutionDetails;
 import org.apache.james.webadmin.dto.DTOModuleInjections;
+import 
org.apache.james.webadmin.service.ClearMailboxContentTaskAdditionalInformationDTO;
 import org.apache.james.webadmin.service.CreateMissingParentsTask;
 import 
org.apache.james.webadmin.service.CreateMissingParentsTaskAdditionalInformationDTO;
 import org.apache.james.webadmin.service.EventDeadLettersRedeliverAllTaskDTO;
@@ -140,4 +141,11 @@ public class WebadminMailboxTaskSerializationModule 
extends AbstractModule {
     public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> webAdminCreateMissingParentsAdditionalInformation() {
         return 
CreateMissingParentsTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
     }
+
+    @Named(DTOModuleInjections.WEBADMIN_DTO)
+    @ProvidesIntoSet
+    public AdditionalInformationDTOModule<? extends 
TaskExecutionDetails.AdditionalInformation, ? extends  
AdditionalInformationDTO> webAdminClearMailboxContentAdditionalInformation() {
+        return 
ClearMailboxContentTaskAdditionalInformationDTO.SERIALIZATION_MODULE;
+    }
+
 }
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 092c2c6..46746ed 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
@@ -35,13 +35,18 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 
 import org.apache.james.core.Username;
+import org.apache.james.mailbox.exception.MailboxException;
 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.Task;
 import org.apache.james.task.TaskManager;
+import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.webadmin.Constants;
 import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.service.ClearMailboxContentTask;
 import org.apache.james.webadmin.service.UserMailboxesService;
+import org.apache.james.webadmin.tasks.TaskFromRequest;
 import org.apache.james.webadmin.tasks.TaskFromRequestRegistry;
 import 
org.apache.james.webadmin.tasks.TaskFromRequestRegistry.TaskRegistration;
 import org.apache.james.webadmin.tasks.TaskIdDto;
@@ -92,6 +97,7 @@ public class UserMailboxesRoutes implements Routes {
     public static final String SPECIFIC_MAILBOX = USER_MAILBOXES_BASE + 
Constants.SEPARATOR + MAILBOX_NAME;
     public static final String MESSAGE_COUNT_PATH = SPECIFIC_MAILBOX + 
"/messageCount";
     public static final String UNSEEN_MESSAGE_COUNT_PATH = SPECIFIC_MAILBOX + 
"/unseenMessageCount";
+    public static final String MESSAGES_PATH = SPECIFIC_MAILBOX + "/messages";
 
     private final UserMailboxesService userMailboxesService;
     private final JsonTransformer jsonTransformer;
@@ -135,6 +141,9 @@ public class UserMailboxesRoutes implements Routes {
             .ifPresent(route -> service.post(USER_MAILBOXES_BASE, route, 
jsonTransformer));
 
         unseenMessageCount();
+
+        TaskFromRequest clearMailboxContentTaskRequest = 
this::clearMailboxContent;
+        service.delete(MESSAGES_PATH, 
clearMailboxContentTaskRequest.asRoute(taskManager), jsonTransformer);
     }
 
     @GET
@@ -425,4 +434,38 @@ public class UserMailboxesRoutes implements Routes {
             }
         });
     }
+
+    @DELETE
+    @Path("/{mailboxName}/messages")
+    @ApiOperation(value = "Clearing content of a given mailbox.", nickname = 
"ClearMailboxContent")
+    @ApiImplicitParams({
+        @ApiImplicitParam(required = true, dataType = "string", name = 
"username", paramType = "path"),
+        @ApiImplicitParam(required = true, dataType = "string", name = 
"mailboxName", paramType = "path")
+    })
+    @ApiResponses(
+        {
+            @ApiResponse(code = HttpStatus.CREATED_201, message = "The taskId 
of the given scheduled task", response = TaskIdDto.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. The `username` or `mailboxName` does not exit"),
+        })
+
+    public Task clearMailboxContent(Request request) throws 
UsersRepositoryException, MailboxException {
+        Username username = getUsernameParam(request);
+        MailboxName mailboxName = new 
MailboxName(request.params(MAILBOX_NAME));
+        try {
+            userMailboxesService.usernamePreconditions(username);
+            userMailboxesService.mailboxExistPreconditions(username, 
mailboxName);
+        } catch (IllegalStateException e) {
+            LOGGER.info("Invalid put 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();
+        }
+
+        return new ClearMailboxContentTask(username, mailboxName, 
userMailboxesService);
+    }
 }
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 dde29fe..f88c4c7 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
@@ -172,10 +172,18 @@ public class UserMailboxesService {
         }
     }
 
-    private void usernamePreconditions(Username username) throws 
UsersRepositoryException {
+    public void usernamePreconditions(Username username) throws 
UsersRepositoryException {
         Preconditions.checkState(usersRepository.contains(username), "User 
does not exist");
     }
 
+    public void mailboxExistPreconditions(Username username, MailboxName 
mailboxName) throws MailboxException {
+        MailboxSession mailboxSession = 
mailboxManager.createSystemSession(username);
+        MailboxPath mailboxPath = MailboxPath.forUser(username, 
mailboxName.asString())
+            .assertAcceptable(mailboxSession.getPathDelimiter());
+        
Preconditions.checkState(Boolean.TRUE.equals(Mono.from(mailboxManager.mailboxExists(mailboxPath,
 mailboxSession)).block()),
+            "Mailbox does not exist. " + mailboxPath.asString());
+    }
+
     private Stream<MailboxMetaData> listUserMailboxes(MailboxSession 
mailboxSession) throws MailboxException {
         return mailboxManager.search(
             MailboxQuery.privateMailboxesBuilder(mailboxSession).build(),
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 4fc7201..53fcf6e 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
@@ -28,6 +28,7 @@ import static org.apache.james.webadmin.Constants.SEPARATOR;
 import static org.apache.james.webadmin.routes.UserMailboxesRoutes.USERS_BASE;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.eclipse.jetty.http.HttpStatus.BAD_REQUEST_400;
+import static org.eclipse.jetty.http.HttpStatus.CREATED_201;
 import static org.eclipse.jetty.http.HttpStatus.INTERNAL_SERVER_ERROR_500;
 import static org.eclipse.jetty.http.HttpStatus.NOT_FOUND_404;
 import static org.eclipse.jetty.http.HttpStatus.NO_CONTENT_204;
@@ -108,6 +109,8 @@ 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;
+import org.apache.james.webadmin.service.ClearMailboxContentTask;
+import 
org.apache.james.webadmin.service.ClearMailboxContentTaskAdditionalInformationDTO;
 import org.apache.james.webadmin.service.UserMailboxesService;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.apache.mailbox.tools.indexer.ReIndexerImpl;
@@ -170,7 +173,8 @@ class UserMailboxesRoutesTest {
                     taskManager,
                     ImmutableSet.of(new 
UserMailboxesRoutes.UserReIndexingTaskRegistration(reIndexer))),
                 new TasksRoutes(taskManager, new JsonTransformer(),
-                    
DTOConverter.of(WebAdminUserReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory))))
+                    
DTOConverter.of(WebAdminUserReindexingTaskAdditionalInformationDTO.serializationModule(mailboxIdFactory),
+                        
ClearMailboxContentTaskAdditionalInformationDTO.SERIALIZATION_MODULE)))
             .start();
 
         RestAssured.requestSpecification = 
WebAdminUtils.buildRequestSpecification(webAdminServer)
@@ -1114,6 +1118,63 @@ class UserMailboxesRoutesTest {
                 .containsEntry("message", "Invalid get on user mailboxes")
                 .containsEntry("details", String.format("#private:%s:%s can 
not be found", USERNAME.asString(), MAILBOX_NAME));
         }
+
+        @Test
+        void deleteMailboxContentShouldReturnErrorWhenUserIsNotFound() throws 
UsersRepositoryException {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            Map<String, Object> errors = when()
+                .delete(MAILBOX_NAME + "/messages")
+            .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 deleteMailboxContentShouldReturnErrorWhenMailboxDoesNotExist() {
+            Map<String, Object> errors = when()
+                .delete(MAILBOX_NAME + "/messages")
+            .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("Mailbox does not 
exist. #private:%s:%s", USERNAME.asString(), MAILBOX_NAME));
+        }
+
+        @Test
+        void deleteMailboxContentShouldReturnTaskId() {
+            with()
+                .put(MAILBOX_NAME);
+
+            String taskId = when()
+                .delete(MAILBOX_NAME + "/messages")
+            .then()
+                .statusCode(CREATED_201)
+                .extract()
+                .jsonPath()
+                .get("taskId");
+
+            assertThat(taskId)
+                .isNotEmpty();
+        }
     }
 
     @Nested
@@ -1804,6 +1865,135 @@ class UserMailboxesRoutesTest {
                 assertThat(searchIndex.retrieveIndexedFlags(mailbox, 
uid).blockOptional())
                     .isEmpty();
             }
+
+            @Test
+            void 
userReprocessingShouldReturnTaskDetailWhenDeleteMailboxContentWithNoEmail() {
+                with()
+                    .put(MAILBOX_NAME);
+
+                String taskId = when()
+                    .delete(MAILBOX_NAME + "/messages")
+                    .jsonPath()
+                    .get("taskId");
+
+                given()
+                    .basePath(TasksRoutes.BASE)
+                .when()
+                    .get(taskId + "/await")
+                .then()
+                    .body("status", Matchers.is("completed"))
+                    .body("taskId", Matchers.is(notNullValue()))
+                    .body("type", 
Matchers.is(ClearMailboxContentTask.TASK_TYPE.asString()))
+                    .body("startedDate", Matchers.is(notNullValue()))
+                    .body("submitDate", Matchers.is(notNullValue()))
+                    .body("completedDate", Matchers.is(notNullValue()))
+                    .body("additionalInformation.username", 
Matchers.is(USERNAME.asString()))
+                    .body("additionalInformation.mailboxName", 
Matchers.is(MAILBOX_NAME))
+                    .body("additionalInformation.messagesSuccessCount", 
Matchers.is(0))
+                    .body("additionalInformation.messagesFailCount", 
Matchers.is(0));
+            }
+
+            @Test
+            void 
userReprocessingShouldReturnTaskDetailWhenDeleteMailboxContentWithHasEmails() {
+                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 taskId = when()
+                    .delete(MAILBOX_NAME + "/messages")
+                    .jsonPath()
+                    .get("taskId");
+
+                given()
+                    .basePath(TasksRoutes.BASE)
+                .when()
+                    .get(taskId + "/await")
+                    .then()
+                    .body("status", Matchers.is("completed"))
+                    .body("taskId", Matchers.is(notNullValue()))
+                    .body("type", 
Matchers.is(ClearMailboxContentTask.TASK_TYPE.asString()))
+                    .body("startedDate", Matchers.is(notNullValue()))
+                    .body("submitDate", Matchers.is(notNullValue()))
+                    .body("completedDate", Matchers.is(notNullValue()))
+                    .body("additionalInformation.username", 
Matchers.is(USERNAME.asString()))
+                    .body("additionalInformation.mailboxName", 
Matchers.is(MAILBOX_NAME))
+                    .body("additionalInformation.messagesSuccessCount", 
Matchers.is(10))
+                    .body("additionalInformation.messagesFailCount", 
Matchers.is(0));
+            }
+
+            @Test
+            void userReprocessingShouldEmptyMailboxWhenDeleteMailboxContent() 
throws MailboxException {
+                with()
+                    .put(MAILBOX_NAME);
+
+                MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, 
MAILBOX_NAME);
+                MailboxSession systemSession = 
mailboxManager.createSystemSession(USERNAME);
+
+                mailboxManager.getMailbox(mailboxPath, systemSession)
+                    .appendMessage(
+                        MessageManager.AppendCommand.builder()
+                            .build("header: value\r\n\r\nbody"),
+                        systemSession);
+
+                String taskId = when()
+                    .delete(MAILBOX_NAME + "/messages")
+                    .jsonPath()
+                    .get("taskId");
+
+                given()
+                    .basePath(TasksRoutes.BASE)
+                .when()
+                    .get(taskId + "/await");
+
+                assertThat(mailboxManager.getMailbox(mailboxPath, 
systemSession).getMailboxCounters(systemSession).getCount())
+                    .isEqualTo(0);
+            }
+
+            @Test
+            void 
userReprocessingShouldNotClearUnRelatedMailboxWhenDeleteMailboxContent() throws 
MailboxException {
+                with()
+                    .put(MAILBOX_NAME);
+
+                String unRelatedMailbox = "unRelatedMailbox";
+                with()
+                    .put(unRelatedMailbox);
+                MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, 
unRelatedMailbox);
+                MailboxSession systemSession = 
mailboxManager.createSystemSession(USERNAME);
+
+                mailboxManager.getMailbox(mailboxPath, systemSession)
+                    .appendMessage(
+                        MessageManager.AppendCommand.builder()
+                            .build("header: value\r\n\r\nbody"),
+                        systemSession);
+
+                String taskId = when()
+                    .delete(MAILBOX_NAME + "/messages")
+                    .jsonPath()
+                    .get("taskId");
+
+                given()
+                    .basePath(TasksRoutes.BASE)
+                .when()
+                    .get(taskId + "/await");
+
+                assertThat(mailboxManager.getMailbox(mailboxPath, 
systemSession).getMailboxCounters(systemSession).getCount())
+                    .isEqualTo(1);
+            }
         }
 
         @Nested

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to