This is an automated email from the ASF dual-hosted git repository.

Arsnael pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 6e4318163b5c732ede1c9e3108ca1c2aa44008d1
Author: Rene Cordier <[email protected]>
AuthorDate: Tue May 19 12:06:31 2026 +0700

    JAMES-4204 Add a force parameter to restore backup webadmin route
---
 .../james/mailbox/backup/DefaultMailboxBackup.java | 48 ++++++++++++------
 .../apache/james/mailbox/backup/MailboxBackup.java |  3 +-
 .../mailbox/backup/DefaultMailboxBackupTest.java   | 58 ++++++++++++++++++++--
 .../service/MailboxesRestoreRequestToTask.java     |  6 ++-
 .../webadmin/service/MailboxesRestoreTask.java     | 12 ++++-
 .../webadmin/service/MailboxesRestoreTaskDTO.java  | 15 ++++--
 .../james/webadmin/service/RestoreService.java     | 49 ++++++++++++------
 .../service/MailboxesRestoreRequestToTaskTest.java | 15 ++++--
 .../james/webadmin/service/RestoreServiceTest.java | 35 +++++++++++++
 .../test/resources/json/mailboxesRestore.task.json |  3 +-
 10 files changed, 200 insertions(+), 44 deletions(-)

diff --git 
a/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/DefaultMailboxBackup.java
 
b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/DefaultMailboxBackup.java
index e8c964270b..f1a7acba1d 100644
--- 
a/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/DefaultMailboxBackup.java
+++ 
b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/DefaultMailboxBackup.java
@@ -100,24 +100,17 @@ public class DefaultMailboxBackup implements 
MailboxBackup {
         mailboxManager.endProcessingRequest(session);
     }
 
-    private boolean isAccountNonEmpty(Username username) throws 
MailboxException {
-        MailboxSession session = mailboxManager.createSystemSession(username);
-        try {
-            return getAccountContentForUser(session)
-                .stream()
-                .findFirst()
-                .isPresent();
-        } finally {
-            mailboxManager.endProcessingRequest(session);
-        }
-    }
-
     @Override
-    public Publisher<BackupStatus> restore(Username username, InputStream 
source) {
+    public Publisher<BackupStatus> restore(Username username, InputStream 
source, boolean force) {
         try {
             if (isAccountNonEmpty(username)) {
-                LOGGER.warn("Warning, account should be empty before 
performing a restoration for user: {}", username);
-                return Mono.just(BackupStatus.NON_EMPTY_RECEIVER_ACCOUNT);
+                if (force) {
+                    LOGGER.warn("Force restore: deleting existing mailbox data 
for user: {}", username);
+                    clearAccountContent(username);
+                } else {
+                    LOGGER.warn("Warning, account should be empty before 
performing a restoration for user: {}", username);
+                    return Mono.just(BackupStatus.NON_EMPTY_RECEIVER_ACCOUNT);
+                }
             }
         } catch (Exception e) {
             LOGGER.error("Error during account restoration for user : " + 
username.asString(), e);
@@ -132,6 +125,31 @@ public class DefaultMailboxBackup implements MailboxBackup 
{
             .onErrorReturn(BackupStatus.FAILED);
     }
 
+    private void clearAccountContent(Username username) throws 
MailboxException {
+        MailboxSession session = mailboxManager.createSystemSession(username);
+        try {
+            List<MailAccountContent> accountContents = 
getAccountContentForUser(session);
+            for (MailAccountContent content : accountContents) {
+                MailboxPath path = 
content.getMailboxWithAnnotations().mailbox.generateAssociatedPath();
+                mailboxManager.deleteMailbox(path, session);
+            }
+        } finally {
+            mailboxManager.endProcessingRequest(session);
+        }
+    }
+
+    private boolean isAccountNonEmpty(Username username) throws 
MailboxException {
+        MailboxSession session = mailboxManager.createSystemSession(username);
+        try {
+            return getAccountContentForUser(session)
+                .stream()
+                .findFirst()
+                .isPresent();
+        } finally {
+            mailboxManager.endProcessingRequest(session);
+        }
+    }
+
     private Stream<MailAccountContent> 
getMailboxWithAnnotationsFromPath(MailboxSession session, MailboxPath path) {
         try {
             MessageManager messageManager = mailboxManager.getMailbox(path, 
session);
diff --git 
a/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/MailboxBackup.java
 
b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/MailboxBackup.java
index 3b182833f3..4ac8622d11 100644
--- 
a/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/MailboxBackup.java
+++ 
b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/MailboxBackup.java
@@ -42,8 +42,9 @@ public interface MailboxBackup {
     /**
      * @param username   the user in which account the restored elements will 
be stored.
      * @param source the input stream to the archive containing the account 
elements.
+     * @param force if true, delete the user's existing mailbox data before 
restoring.
      * @return a Publisher indicating when the action is completed
      */
-    Publisher<BackupStatus> restore(Username username, InputStream source) 
throws IOException, MailboxException;
+    Publisher<BackupStatus> restore(Username username, InputStream source, 
boolean force) throws IOException, MailboxException;
 
 }
diff --git 
a/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/DefaultMailboxBackupTest.java
 
b/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/DefaultMailboxBackupTest.java
index c67f15b301..dd65a6c575 100644
--- 
a/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/DefaultMailboxBackupTest.java
+++ 
b/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/DefaultMailboxBackupTest.java
@@ -47,6 +47,7 @@ import reactor.core.publisher.Mono;
 
 class DefaultMailboxBackupTest implements MailboxMessageFixture {
     private static final int BUFFER_SIZE = 4096;
+    private static final boolean FORCE_RESTORE = true;
     private static final String EXPECTED_ANNOTATIONS_DIR = "annotations";
 
     private final ArchiveService archiveService = new Zipper();
@@ -169,7 +170,7 @@ class DefaultMailboxBackupTest implements 
MailboxMessageFixture {
         backup.backupAccount(USERNAME_1, destination);
 
         InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
-        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source)).block();
+        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source, !FORCE_RESTORE)).block();
         assertThat(backupStatus).isEqualTo(MailboxBackup.BackupStatus.DONE);
         List<DefaultMailboxBackup.MailAccountContent> content = 
backup.getAccountContentForUser(sessionOtherUser);
 
@@ -184,7 +185,7 @@ class DefaultMailboxBackupTest implements 
MailboxMessageFixture {
         backup.backupAccount(USERNAME_1, destination);
 
         InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
-        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source)).block();
+        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source, !FORCE_RESTORE)).block();
         assertThat(backupStatus).isEqualTo(MailboxBackup.BackupStatus.DONE);
 
         List<DefaultMailboxBackup.MailAccountContent> content = 
backup.getAccountContentForUser(sessionOtherUser);
@@ -205,11 +206,33 @@ class DefaultMailboxBackupTest implements 
MailboxMessageFixture {
         backup.backupAccount(USERNAME_1, destination);
 
         InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
-        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source)).block();
+        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source, !FORCE_RESTORE)).block();
 
         
assertThat(backupStatus).isEqualTo(MailboxBackup.BackupStatus.NON_EMPTY_RECEIVER_ACCOUNT);
     }
 
+    @Test
+    void 
restoringAccountInNonEmptyAccountWithForceShouldDeleteExistingAndRestore() 
throws Exception {
+        createMailbox(sessionUser, MAILBOX_PATH_USER1_MAILBOX1);
+        createMailbox(sessionOtherUser, MAILBOX_PATH_OTHER_USER_MAILBOX1);
+
+        ByteArrayOutputStream destination = new 
ByteArrayOutputStream(BUFFER_SIZE);
+        backup.backupAccount(USERNAME_1, destination);
+
+        InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
+        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source, true)).block();
+
+        assertThat(backupStatus).isEqualTo(MailboxBackup.BackupStatus.DONE);
+
+        List<DefaultMailboxBackup.MailAccountContent> content = 
backup.getAccountContentForUser(sessionOtherUser);
+
+        assertThat(content).hasSize(1);
+        DefaultMailboxBackup.MailAccountContent mailAccountContent = 
content.get(0);
+        Mailbox mailbox = 
mailAccountContent.getMailboxWithAnnotations().mailbox;
+        assertThat(mailbox.getName()).isEqualTo(MAILBOX_1_NAME);
+        assertThat(mailAccountContent.getMessages().count()).isEqualTo(0);
+    }
+
     @Test
     void 
backupAccountWithTwoMailboxesThenRestoringItInUser2AccountShouldCreateTwoMailboxes()
 throws Exception {
         createMailbox(sessionUser, MAILBOX_PATH_USER1_MAILBOX1);
@@ -219,7 +242,7 @@ class DefaultMailboxBackupTest implements 
MailboxMessageFixture {
         backup.backupAccount(USERNAME_1, destination);
 
         InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
-        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source)).block();
+        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source, !FORCE_RESTORE)).block();
 
         assertThat(backupStatus).isEqualTo(MailboxBackup.BackupStatus.DONE);
 
@@ -237,6 +260,33 @@ class DefaultMailboxBackupTest implements 
MailboxMessageFixture {
         assertThat(contentMailbox2.getMessages().count()).isEqualTo(0);
     }
 
+    @Test
+    void doRestoreWithTwoMailboxesAndOneMessageBackupShouldRestoreEntries() 
throws Exception {
+        ByteArrayOutputStream destination = new 
ByteArrayOutputStream(BUFFER_SIZE);
+        createMailboxWithMessages(sessionUser, MAILBOX_PATH_USER1_MAILBOX1, 
getMessage1AppendCommand());
+        createMailboxWithMessages(sessionUser, MAILBOX_PATH_USER1_MAILBOX2, 
getMessage1AppendCommand());
+
+        backup.backupAccount(USERNAME_1, destination);
+
+        InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
+        MailboxBackup.BackupStatus backupStatus = 
Mono.from(backup.restore(USERNAME_2, source, !FORCE_RESTORE)).block();
+
+        assertThat(backupStatus).isEqualTo(MailboxBackup.BackupStatus.DONE);
+
+        List<DefaultMailboxBackup.MailAccountContent> content = 
backup.getAccountContentForUser(sessionOtherUser);
+
+        assertThat(content).hasSize(2);
+        DefaultMailboxBackup.MailAccountContent contentMailbox1 = 
content.get(0);
+        Mailbox mailbox1 = contentMailbox1.getMailboxWithAnnotations().mailbox;
+        assertThat(mailbox1.getName()).isEqualTo(MAILBOX_1_NAME);
+        assertThat(contentMailbox1.getMessages().count()).isEqualTo(1);
+
+        DefaultMailboxBackup.MailAccountContent contentMailbox2 = 
content.get(1);
+        Mailbox mailbox2 = contentMailbox2.getMailboxWithAnnotations().mailbox;
+        assertThat(mailbox2.getName()).isEqualTo(MAILBOX_2_NAME);
+        assertThat(contentMailbox2.getMessages().count()).isEqualTo(1);
+    }
+
     private MessageManager.AppendCommand getMessage1AppendCommand() throws 
IOException {
         return MessageManager.AppendCommand.builder()
             .withFlags(flags1)
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTask.java
 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTask.java
index 0b95d3efe2..e8e25f8983 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTask.java
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTask.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.webadmin.service;
 
+import java.util.Optional;
+
 import jakarta.inject.Inject;
 
 import org.apache.james.blob.api.BlobId;
@@ -69,6 +71,8 @@ public class MailboxesRestoreRequestToTask extends 
TaskFromRequestRegistry.TaskR
 
         BlobId blobId = 
Mono.from(blobStore.save(blobStore.getDefaultBucketName(), data, 
BlobStore.StoragePolicy.LOW_COST)).block();
 
-        return new MailboxesRestoreTask(restoreService, username, blobId);
+        Optional<Boolean> force = 
Optional.of(Boolean.parseBoolean(request.queryParams("force")));
+
+        return new MailboxesRestoreTask(restoreService, username, blobId, 
force);
     }
 }
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTask.java
 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTask.java
index e7365e0b8d..a7a876fc98 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTask.java
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTask.java
@@ -54,16 +54,22 @@ public class MailboxesRestoreTask implements Task {
     private final Username username;
     private final RestoreService service;
     private final BlobId blobId;
+    private final Optional<Boolean> force;
 
     MailboxesRestoreTask(RestoreService service, Username username, BlobId 
blobId) {
+        this(service, username, blobId, Optional.of(false));
+    }
+
+    MailboxesRestoreTask(RestoreService service, Username username, BlobId 
blobId, Optional<Boolean> force) {
         this.username = username;
         this.service = service;
         this.blobId = blobId;
+        this.force = force;
     }
 
     @Override
     public Result run() {
-        return service.restore(username, blobId)
+        return service.restore(username, blobId, force.orElse(false))
             .block();
     }
 
@@ -80,6 +86,10 @@ public class MailboxesRestoreTask implements Task {
         return blobId;
     }
 
+    public Optional<Boolean> isForce() {
+        return force;
+    }
+
     @Override
     public Optional<TaskExecutionDetails.AdditionalInformation> details() {
         return Optional.of(new AdditionalInformation(username,
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTaskDTO.java
 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTaskDTO.java
index 1307e53250..2fb54397f9 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTaskDTO.java
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/MailboxesRestoreTaskDTO.java
@@ -21,6 +21,8 @@ package org.apache.james.webadmin.service;
 
 import static org.apache.james.webadmin.service.MailboxesRestoreTask.TASK_TYPE;
 
+import java.util.Optional;
+
 import org.apache.james.blob.api.BlobId;
 import org.apache.james.core.Username;
 import org.apache.james.json.DTOModule;
@@ -33,13 +35,16 @@ public class MailboxesRestoreTaskDTO implements TaskDTO {
     private final String type;
     private final String username;
     private final String blobId;
+    private final Optional<Boolean> force;
 
     public MailboxesRestoreTaskDTO(@JsonProperty("type") String type,
                                    @JsonProperty("username") String username,
-                                   @JsonProperty("blobId") String blobId) {
+                                   @JsonProperty("blobId") String blobId,
+                                   @JsonProperty("force") Optional<Boolean> 
force) {
         this.type = type;
         this.username = username;
         this.blobId = blobId;
+        this.force = force;
     }
 
     @Override
@@ -55,6 +60,10 @@ public class MailboxesRestoreTaskDTO implements TaskDTO {
         return blobId;
     }
 
+    public Optional<Boolean> getForce() {
+        return force;
+    }
+
     public static TaskDTOModule<MailboxesRestoreTask, MailboxesRestoreTaskDTO> 
module(RestoreService service, BlobId.Factory blobIdFactory) {
         return DTOModule
             .forDomainObject(MailboxesRestoreTask.class)
@@ -66,10 +75,10 @@ public class MailboxesRestoreTaskDTO implements TaskDTO {
     }
 
     public MailboxesRestoreTask fromDTO(RestoreService service, BlobId.Factory 
blobIdFactory) {
-        return new MailboxesRestoreTask(service, Username.of(username), 
blobIdFactory.of(blobId));
+        return new MailboxesRestoreTask(service, Username.of(username), 
blobIdFactory.parse(blobId), force);
     }
 
     public static MailboxesRestoreTaskDTO toDTO(MailboxesRestoreTask 
domainObject, String typeName) {
-        return new MailboxesRestoreTaskDTO(typeName, 
domainObject.getUsername().asString(), domainObject.getBlobId().asString());
+        return new MailboxesRestoreTaskDTO(typeName, 
domainObject.getUsername().asString(), domainObject.getBlobId().asString(), 
domainObject.isForce());
     }
 }
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/RestoreService.java
 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/RestoreService.java
index 54c47188bf..b2b42e5b27 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/RestoreService.java
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/RestoreService.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.webadmin.service;
 
+import java.io.IOException;
 import java.io.InputStream;
 
 import jakarta.inject.Inject;
@@ -47,26 +48,44 @@ public class RestoreService {
     }
 
     public Mono<Task.Result> restore(Username username, BlobId blobId) {
-        try (InputStream inputStream = 
blobStore.read(blobStore.getDefaultBucketName(), blobId)) {
-            return restore(username, inputStream);
-        } catch (Exception e) {
-            LOGGER.error("Error restoring mailboxes for user {}", 
username.asString(), e);
-            return Mono.just(Task.Result.PARTIAL);
-        } finally {
-            try {
-                Mono.from(blobStore.delete(blobStore.getDefaultBucketName(), 
blobId)).block();
-            } catch (Exception e) {
-                LOGGER.error("Error deleting blob {} after restore", 
blobId.asString(), e);
-            }
+        return restore(username, blobId, false);
+    }
+
+    public Mono<Task.Result> restore(Username username, BlobId blobId, boolean 
force) {
+        return Mono.fromCallable(() -> 
blobStore.read(blobStore.getDefaultBucketName(), blobId))
+            .flatMap(inputStream -> {
+                try {
+                    return Mono.from(mailboxBackup.restore(username, 
inputStream, force))
+                        .map(this::computeTaskResult)
+                        .doFinally(signalType -> {
+                            closeStream(inputStream);
+                            deleteBlob(blobId);
+                        });
+                } catch (Exception e) {
+                    closeStream(inputStream);
+                    deleteBlob(blobId);
+                    return Mono.error(e);
+                }
+            })
+            .onErrorResume(e -> {
+                LOGGER.error("Error restoring mailboxes for user {}", 
username.asString(), e);
+                return Mono.just(Task.Result.PARTIAL);
+            });
+    }
+
+    private void closeStream(InputStream inputStream) {
+        try {
+            inputStream.close();
+        } catch (IOException e) {
+            LOGGER.error("Error closing input stream after restore", e);
         }
     }
 
-    private Mono<Task.Result> restore(Username username, InputStream source) {
+    private void deleteBlob(BlobId blobId) {
         try {
-            return Mono.from(mailboxBackup.restore(username, source))
-                .map(this::computeTaskResult);
+            Mono.from(blobStore.delete(blobStore.getDefaultBucketName(), 
blobId)).block();
         } catch (Exception e) {
-            return Mono.error(e);
+            LOGGER.error("Error deleting blob {} after restore", 
blobId.asString(), e);
         }
     }
 
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTaskTest.java
 
b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTaskTest.java
index 72ba4ef92f..e80c44b944 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTaskTest.java
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesRestoreRequestToTaskTest.java
@@ -28,9 +28,7 @@ import static org.hamcrest.Matchers.notNullValue;
 import java.io.ByteArrayOutputStream;
 import java.util.zip.ZipOutputStream;
 
-import org.apache.james.blob.api.BlobId;
 import org.apache.james.blob.api.BlobStore;
-import org.apache.james.blob.api.PlainBlobId;
 import org.apache.james.blob.export.file.FileSystemExtension;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.json.DTOConverter;
@@ -87,7 +85,6 @@ class MailboxesRestoreRequestToTaskTest {
     }
 
     private static final String BASE_PATH = "users/:username/mailboxes";
-    private static final BlobId.Factory BLOB_ID_FACTORY = new 
PlainBlobId.Factory();
 
     private WebAdminServer webAdminServer;
     private MemoryTaskManager taskManager;
@@ -215,6 +212,18 @@ class MailboxesRestoreRequestToTaskTest {
             .body("taskId", is(notNullValue()));
     }
 
+    @Test
+    void postShouldCreateANewTaskWithForceTrue() throws Exception {
+        given()
+            .queryParam("task", "restore")
+            .queryParam("force", "true")
+            .body(emptyZip())
+            .post()
+        .then()
+            .statusCode(HttpStatus.CREATED_201)
+            .body("taskId", is(notNullValue()));
+    }
+
     @Test
     void restoreMailboxesShouldCompleteWhenUserHasNoMailbox() throws Exception 
{
         String taskId = given()
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/RestoreServiceTest.java
 
b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/RestoreServiceTest.java
index a983e1382e..5eab10a74e 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/RestoreServiceTest.java
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/RestoreServiceTest.java
@@ -115,6 +115,41 @@ class RestoreServiceTest {
             .isEqualTo(Task.Result.PARTIAL);
     }
 
+    @Test
+    void restoreWithForceShouldReturnCompleteWhenNonEmptyAccount() throws 
Exception {
+        createAMailboxWithAMail();
+
+        ByteArrayOutputStream destination = new 
ByteArrayOutputStream(BUFFER_SIZE);
+        testSystem.backup.backupAccount(BOB, destination);
+
+        InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
+        BlobId blobId = 
Mono.from(testSystem.blobStore.save(testSystem.blobStore.getDefaultBucketName(),
 source, BlobStore.StoragePolicy.LOW_COST)).block();
+
+        assertThat(testee.restore(BOB, blobId, true).block())
+            .isEqualTo(Task.Result.COMPLETED);
+    }
+
+    @Test
+    void restoreWithForceShouldDeleteExistingAndRestoreContent() throws 
Exception {
+        createAMailboxWithAMail();
+
+        ByteArrayOutputStream destination = new 
ByteArrayOutputStream(BUFFER_SIZE);
+        testSystem.backup.backupAccount(BOB, destination);
+
+        InputStream source = new 
ByteArrayInputStream(destination.toByteArray());
+        BlobId blobId = 
Mono.from(testSystem.blobStore.save(testSystem.blobStore.getDefaultBucketName(),
 source, BlobStore.StoragePolicy.LOW_COST)).block();
+
+        testee.restore(BOB, blobId, true).block();
+
+        MailboxSession bobSession = 
testSystem.mailboxManager.createSystemSession(BOB);
+        MessageManager mailbox = 
testSystem.mailboxManager.getMailbox(MailboxPath.inbox(BOB), bobSession);
+        MessageResultIterator resultIterator = 
mailbox.getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, bobSession);
+        assertThat(resultIterator).toIterable()
+            .hasSize(1)
+            .first()
+            .satisfies(result -> assertThat(new 
String(result.getFullContent().getInputStream().readAllBytes())).isEqualTo(MESSAGE_CONTENT));
+    }
+
     @Test
     void restoreShouldReturnPartialWhenFailed() throws Exception {
         doThrow(new RuntimeException())
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/test/resources/json/mailboxesRestore.task.json
 
b/server/protocols/webadmin/webadmin-mailbox/src/test/resources/json/mailboxesRestore.task.json
index c19fc26185..92d960bd3e 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/test/resources/json/mailboxesRestore.task.json
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/test/resources/json/mailboxesRestore.task.json
@@ -1,5 +1,6 @@
 {
   "type":"MailboxesRestoreTask",
   "username": "bob",
-  "blobId": "abc123"
+  "blobId": "abc123",
+  "force": false
 }


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

Reply via email to