You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2020/12/07 03:57:34 UTC

[james-project] 04/13: JAMES-3435 Migration task for CassandraACLDAOV2 adoption

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 461d1c657b6ac78266eed28eebf26244cb191fa9
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Dec 2 14:21:40 2020 +0700

    JAMES-3435 Migration task for CassandraACLDAOV2 adoption
---
 .../versions/CassandraSchemaVersionManager.java    |   2 +-
 .../mailbox/cassandra/mail/CassandraACLDAOV2.java  |   3 +-
 .../mailbox/cassandra/mail/CassandraACLMapper.java |  37 +++++--
 .../cassandra/mail/migration/AclV2Migration.java   | 115 +++++++++++++++++++++
 ...AclV2MigrationTaskAdditionalInformationDTO.java |  69 +++++++++++++
 .../mail/migration/AclV2MigrationTaskDTO.java      |  59 +++++++++++
 .../cassandra/CassandraMailboxManagerTest.java     |   7 +-
 .../cassandra/mail/CassandraACLMapperContract.java |   8 +-
 .../cassandra/mail/CassandraACLMapperV1Test.java   |  34 +++---
 .../cassandra/mail/CassandraACLMapperV2Test.java   |  36 ++++---
 .../cassandra/mail/CassandraMailboxMapperTest.java |   4 +-
 .../AclV2MigrationTaskSerializationTest.java       |  52 ++++++++++
 .../mail/migration/AclV2MigrationTest.java         | 112 ++++++++++++++++++++
 .../mail/migration/MailboxPathV2MigrationTest.java |   5 +-
 .../modules/mailbox/CassandraMailboxModule.java    |   2 +
 .../modules/webadmin/CassandraRoutesModule.java    |   3 +
 16 files changed, 500 insertions(+), 48 deletions(-)

diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java
index 29dae94..992c579 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/versions/CassandraSchemaVersionManager.java
@@ -36,7 +36,7 @@ import reactor.core.publisher.Mono;
 
 public class CassandraSchemaVersionManager {
     public static final SchemaVersion MIN_VERSION = new SchemaVersion(5);
-    public static final SchemaVersion MAX_VERSION = new SchemaVersion(9);
+    public static final SchemaVersion MAX_VERSION = new SchemaVersion(10);
     public static final SchemaVersion DEFAULT_VERSION = MIN_VERSION;
 
     private static final Logger LOGGER = LoggerFactory.getLogger(CassandraSchemaVersionManager.class);
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLDAOV2.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLDAOV2.java
index 9bc2ad3..c9e6339 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLDAOV2.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLDAOV2.java
@@ -136,6 +136,7 @@ public class CassandraACLDAOV2 implements CassandraACLDAO {
 
     public Mono<ACLDiff> setACL(CassandraId cassandraId, MailboxACL mailboxACL) {
         return getACL(cassandraId)
+            .switchIfEmpty(Mono.just(MailboxACL.EMPTY))
             .flatMap(oldACL -> delete(cassandraId)
                 .then(Flux.fromIterable(mailboxACL.getEntries().entrySet())
                     .concatMap(entry -> doSetACL(cassandraId, mailboxACL))
@@ -174,7 +175,7 @@ public class CassandraACLDAOV2 implements CassandraACLDAO {
             .collect(Guavate.toImmutableSet());
     }
 
-    private Mono<Void> doSetACL(CassandraId cassandraId, MailboxACL mailboxACL) {
+    public Mono<Void> doSetACL(CassandraId cassandraId, MailboxACL mailboxACL) {
         BatchStatement batchStatement = new BatchStatement();
         mailboxACL.getEntries().entrySet()
             .stream().map(entry -> replaceRights.bind()
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
index 7a6e1a8..d9c8123 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
@@ -21,6 +21,8 @@ package org.apache.james.mailbox.cassandra.mail;
 
 import javax.inject.Inject;
 
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
+import org.apache.james.backends.cassandra.versions.SchemaVersion;
 import org.apache.james.mailbox.acl.ACLDiff;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -29,35 +31,52 @@ import org.apache.james.mailbox.model.MailboxACL;
 import reactor.core.publisher.Mono;
 
 public class CassandraACLMapper {
+    public static final SchemaVersion ACL_V2_SCHEME_VERSION = new SchemaVersion(10);
     private final CassandraUserMailboxRightsDAO userMailboxRightsDAO;
-    private final CassandraACLDAO cassandraACLDAO;
+    private final CassandraACLDAOV1 cassandraACLDAOV1;
+    private final CassandraACLDAOV2 cassandraACLDAOV2;
+    private final CassandraSchemaVersionManager versionManager;
 
     @Inject
     public CassandraACLMapper(CassandraUserMailboxRightsDAO userMailboxRightsDAO,
-                              CassandraACLDAO cassandraACLDAO) {
-        this.cassandraACLDAO = cassandraACLDAO;
+                              CassandraACLDAOV1 cassandraACLDAOV1,
+                              CassandraACLDAOV2 cassandraACLDAOV2,
+                              CassandraSchemaVersionManager versionManager) {
+        this.cassandraACLDAOV1 = cassandraACLDAOV1;
+        this.cassandraACLDAOV2 = cassandraACLDAOV2;
         this.userMailboxRightsDAO = userMailboxRightsDAO;
+        this.versionManager = versionManager;
+    }
+
+    private Mono<CassandraACLDAO> aclDao() {
+        return versionManager.isBefore(ACL_V2_SCHEME_VERSION)
+            .map(isBefore -> {
+                if (isBefore) {
+                    return cassandraACLDAOV1;
+                }
+                return cassandraACLDAOV2;
+            });
     }
 
     public Mono<MailboxACL> getACL(CassandraId cassandraId) {
-        return cassandraACLDAO.getACL(cassandraId);
+        return aclDao().flatMap(dao -> dao.getACL(cassandraId));
     }
 
     public Mono<ACLDiff> updateACL(CassandraId cassandraId, MailboxACL.ACLCommand command) {
-        return cassandraACLDAO.updateACL(cassandraId, command)
+        return aclDao().flatMap(dao -> dao.updateACL(cassandraId, command)
             .flatMap(aclDiff -> userMailboxRightsDAO.update(cassandraId, aclDiff)
             .thenReturn(aclDiff))
-            .switchIfEmpty(Mono.error(new MailboxException("Unable to update ACL")));
+            .switchIfEmpty(Mono.error(new MailboxException("Unable to update ACL"))));
     }
 
     public Mono<ACLDiff> setACL(CassandraId cassandraId, MailboxACL mailboxACL) {
-        return cassandraACLDAO.setACL(cassandraId, mailboxACL)
+        return aclDao().flatMap(dao -> dao.setACL(cassandraId, mailboxACL)
             .flatMap(aclDiff -> userMailboxRightsDAO.update(cassandraId, aclDiff)
             .thenReturn(aclDiff))
-            .switchIfEmpty(Mono.defer(() -> Mono.error(new MailboxException("Unable to update ACL"))));
+            .switchIfEmpty(Mono.defer(() -> Mono.error(new MailboxException("Unable to update ACL")))));
     }
 
     public Mono<Void> delete(CassandraId cassandraId) {
-        return cassandraACLDAO.delete(cassandraId);
+        return aclDao().flatMap(dao -> dao.delete(cassandraId));
     }
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2Migration.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2Migration.java
new file mode 100644
index 0000000..9d6c7df
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2Migration.java
@@ -0,0 +1,115 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail.migration;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.migration.Migration;
+import org.apache.james.mailbox.cassandra.ids.CassandraId;
+import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV1;
+import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV2;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
+import org.apache.james.task.Task;
+import org.apache.james.task.TaskExecutionDetails;
+import org.apache.james.task.TaskType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import reactor.core.scheduler.Schedulers;
+
+public class AclV2Migration implements Migration {
+    private static final int CONCURRENCY = 20;
+
+    static class AclV2MigrationTask implements Task {
+        private final AclV2Migration migration;
+
+        AclV2MigrationTask(AclV2Migration migration) {
+            this.migration = migration;
+        }
+
+        @Override
+        public Result run() throws InterruptedException {
+            return migration.runTask();
+        }
+
+        @Override
+        public TaskType type() {
+            return TYPE;
+        }
+
+        @Override
+        public Optional<TaskExecutionDetails.AdditionalInformation> details() {
+            return Optional.of(migration.getAdditionalInformation());
+        }
+    }
+
+    public static class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation {
+        private final Instant timestamp;
+
+        public AdditionalInformation(Instant timestamp) {
+            this.timestamp = timestamp;
+        }
+
+        @Override
+        public Instant timestamp() {
+            return timestamp;
+        }
+    }
+
+    public static final Logger LOGGER = LoggerFactory.getLogger(AclV2Migration.class);
+    public static final TaskType TYPE = TaskType.of("acl-v2-migration");
+
+    private final CassandraMailboxDAO mailboxDAO;
+    private final CassandraACLDAOV1 daoV1;
+    private final CassandraACLDAOV2 daoV2;
+
+    @Inject
+    public AclV2Migration(CassandraMailboxDAO mailboxDAO, CassandraACLDAOV1 daoV1, CassandraACLDAOV2 daoV2) {
+        this.mailboxDAO = mailboxDAO;
+        this.daoV1 = daoV1;
+        this.daoV2 = daoV2;
+    }
+
+    @Override
+    public void apply() {
+        mailboxDAO.retrieveAllMailboxes()
+            .flatMap(mailbox -> {
+                CassandraId id = (CassandraId) mailbox.getMailboxId();
+                return daoV1.getACL(id)
+                    .flatMap(acl -> daoV2.doSetACL(id, acl));
+            }, CONCURRENCY)
+            .doOnError(t -> LOGGER.error("Error while performing migration", t))
+            .subscribeOn(Schedulers.elastic())
+            .blockLast();
+    }
+
+    @Override
+    public Task asTask() {
+        return new AclV2MigrationTask(this);
+    }
+
+    AdditionalInformation getAdditionalInformation() {
+        return new AdditionalInformation(Clock.systemUTC().instant());
+    }
+}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskAdditionalInformationDTO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskAdditionalInformationDTO.java
new file mode 100644
index 0000000..2726dd0
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskAdditionalInformationDTO.java
@@ -0,0 +1,69 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail.migration;
+
+import java.time.Instant;
+
+import org.apache.james.json.DTOModule;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTOModule;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class AclV2MigrationTaskAdditionalInformationDTO implements AdditionalInformationDTO {
+    private static AclV2MigrationTaskAdditionalInformationDTO fromDomainObject(AclV2Migration.AdditionalInformation additionalInformation, String type) {
+        return new AclV2MigrationTaskAdditionalInformationDTO(
+            type,
+            additionalInformation.timestamp()
+        );
+    }
+
+    public static final AdditionalInformationDTOModule<AclV2Migration.AdditionalInformation, AclV2MigrationTaskAdditionalInformationDTO> MODULE =
+        DTOModule
+            .forDomainObject(AclV2Migration.AdditionalInformation.class)
+            .convertToDTO(AclV2MigrationTaskAdditionalInformationDTO.class)
+            .toDomainObjectConverter(AclV2MigrationTaskAdditionalInformationDTO::toDomainObject)
+            .toDTOConverter(AclV2MigrationTaskAdditionalInformationDTO::fromDomainObject)
+            .typeName(AclV2Migration.TYPE.asString())
+            .withFactory(AdditionalInformationDTOModule::new);
+
+    private final String type;
+    private final Instant timestamp;
+
+    public AclV2MigrationTaskAdditionalInformationDTO(@JsonProperty("type") String type,
+                                                      @JsonProperty("timestamp") Instant timestamp) {
+        this.type = type;
+        this.timestamp = timestamp;
+    }
+
+    @Override
+    public Instant getTimestamp() {
+        return timestamp;
+    }
+
+    @Override
+    public String getType() {
+        return type;
+    }
+
+    private AclV2Migration.AdditionalInformation toDomainObject() {
+        return new AclV2Migration.AdditionalInformation(timestamp);
+    }
+}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskDTO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskDTO.java
new file mode 100644
index 0000000..8ce494d
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskDTO.java
@@ -0,0 +1,59 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail.migration;
+
+import java.util.function.Function;
+
+import org.apache.james.json.DTOModule;
+import org.apache.james.server.task.json.dto.TaskDTO;
+import org.apache.james.server.task.json.dto.TaskDTOModule;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class AclV2MigrationTaskDTO implements TaskDTO {
+
+    private static AclV2MigrationTaskDTO fromDomainObject(AclV2Migration.AclV2MigrationTask task, String type) {
+        return new AclV2MigrationTaskDTO(type);
+    }
+
+    public static final Function<AclV2Migration, TaskDTOModule<AclV2Migration.AclV2MigrationTask, AclV2MigrationTaskDTO>> MODULE = (migration) ->
+        DTOModule
+            .forDomainObject(AclV2Migration.AclV2MigrationTask.class)
+            .convertToDTO(AclV2MigrationTaskDTO.class)
+            .toDomainObjectConverter(dto -> dto.toDomainObject(migration))
+            .toDTOConverter(AclV2MigrationTaskDTO::fromDomainObject)
+            .typeName(AclV2Migration.TYPE.asString())
+            .withFactory(TaskDTOModule::new);
+
+    private final String type;
+
+    public AclV2MigrationTaskDTO(@JsonProperty("type") String type) {
+        this.type = type;
+    }
+
+    @Override
+    public String getType() {
+        return type;
+    }
+
+    private AclV2Migration.AclV2MigrationTask toDomainObject(AclV2Migration migration) {
+        return new AclV2Migration.AclV2MigrationTask(migration);
+    }
+}
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
index cd710d9..f1aa8b2 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
@@ -33,6 +33,8 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
 import org.apache.james.blob.api.BlobStore;
 import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.cassandra.BlobTables;
@@ -45,6 +47,7 @@ import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV1;
+import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraACLMapper;
 import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
@@ -792,7 +795,9 @@ public class CassandraMailboxManagerTest extends MailboxManagerTest<CassandraMai
                 rightsDAO(cassandraCluster),
                 new CassandraACLDAOV1(cassandraCluster.getConf(),
                     CassandraConfiguration.DEFAULT_CONFIGURATION,
-                    cassandra.getCassandraConsistenciesConfiguration()));
+                    cassandra.getCassandraConsistenciesConfiguration()),
+                new CassandraACLDAOV2(cassandraCluster.getConf()),
+                new CassandraSchemaVersionManager(new CassandraSchemaVersionDAO(cassandraCluster.getConf())));
         }
 
         private CassandraUserMailboxRightsDAO rightsDAO(CassandraCluster cassandraCluster) {
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperContract.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperContract.java
index 975bafc..e40d87e 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperContract.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperContract.java
@@ -26,23 +26,17 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 
-import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
-import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.util.concurrent.NamedThreadFactory;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
 
 abstract class CassandraACLMapperContract {
     static final CassandraId MAILBOX_ID = CassandraId.of(UUID.fromString("464765a0-e4e7-11e4-aba4-710c1de3782b"));
 
-    @RegisterExtension
-    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraAclModule.MODULE);
-
     ExecutorService executor;
 
     abstract CassandraACLMapper cassandraACLMapper();
@@ -65,7 +59,7 @@ abstract class CassandraACLMapperContract {
     }
 
     @Test
-    void deleteShouldRemoveACL() throws Exception {
+    void deleteShouldRemoveACL() {
         MailboxACL.EntryKey key = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false);
         MailboxACL.Rfc4314Rights rights = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read);
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java
index e55e158..7cfa3e5 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV1Test.java
@@ -31,9 +31,14 @@ import java.util.concurrent.TimeoutException;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.Scenario.Barrier;
+import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.configuration.CassandraConsistenciesConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
+import org.apache.james.backends.cassandra.versions.SchemaVersion;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.table.CassandraACLTable;
 import org.apache.james.mailbox.model.MailboxACL;
@@ -43,15 +48,22 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraACLMapperV1Test extends CassandraACLMapperContract {
     @RegisterExtension
-    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraAclModule.MODULE);
+    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(
+        CassandraModule.aggregateModules(CassandraAclModule.MODULE, CassandraSchemaVersionModule.MODULE));
 
     private CassandraACLMapper cassandraACLMapper;
 
     @BeforeEach
     void setUp(CassandraCluster cassandra) {
+        CassandraSchemaVersionDAO schemaVersionDAO = new CassandraSchemaVersionDAO(cassandra.getConf());
+        schemaVersionDAO.truncateVersion().block();
+        schemaVersionDAO.updateVersion(new SchemaVersion(9)).block();
+        CassandraSchemaVersionManager versionManager = new CassandraSchemaVersionManager(schemaVersionDAO);
         cassandraACLMapper =  new CassandraACLMapper(
             new CassandraUserMailboxRightsDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
-            new CassandraACLDAOV1(cassandra.getConf(), CassandraConfiguration.DEFAULT_CONFIGURATION, CassandraConsistenciesConfiguration.DEFAULT));
+            new CassandraACLDAOV1(cassandra.getConf(), CassandraConfiguration.DEFAULT_CONFIGURATION, CassandraConsistenciesConfiguration.DEFAULT),
+            new CassandraACLDAOV2(cassandra.getConf()),
+            versionManager);
     }
 
     @Override
@@ -97,8 +109,8 @@ class CassandraACLMapperV1Test extends CassandraACLMapperContract {
         MailboxACL.EntryKey keyBob = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false);
         MailboxACL.Rfc4314Rights rights = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read);
         MailboxACL.EntryKey keyAlice = new MailboxACL.EntryKey("alice", MailboxACL.NameType.user, false);
-        Future<Boolean> future1 = performACLUpdateInExecutor(cassandra, executor, keyBob, rights);
-        Future<Boolean> future2 = performACLUpdateInExecutor(cassandra, executor, keyAlice, rights);
+        Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights);
+        Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights);
 
         barrier.awaitCaller();
         barrier.releaseCaller();
@@ -124,8 +136,8 @@ class CassandraACLMapperV1Test extends CassandraACLMapperContract {
 
         MailboxACL.EntryKey keyBob = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false);
         MailboxACL.EntryKey keyAlice = new MailboxACL.EntryKey("alice", MailboxACL.NameType.user, false);
-        Future<Boolean> future1 = performACLUpdateInExecutor(cassandra, executor, keyBob, rights);
-        Future<Boolean> future2 = performACLUpdateInExecutor(cassandra, executor, keyAlice, rights);
+        Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights);
+        Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights);
 
         barrier.awaitCaller();
         barrier.releaseCaller();
@@ -143,15 +155,9 @@ class CassandraACLMapperV1Test extends CassandraACLMapperContract {
         }
     }
 
-    private Future<Boolean> performACLUpdateInExecutor(CassandraCluster cassandra, ExecutorService executor, MailboxACL.EntryKey key, MailboxACL.Rfc4314Rights rights) {
+    private Future<Boolean> performACLUpdateInExecutor(ExecutorService executor, MailboxACL.EntryKey key, MailboxACL.Rfc4314Rights rights) {
         return executor.submit(() -> {
-            CassandraACLMapper aclMapper = new CassandraACLMapper(
-                new CassandraUserMailboxRightsDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
-                new CassandraACLDAOV1(cassandra.getConf(),
-                    CassandraConfiguration.DEFAULT_CONFIGURATION,
-                    cassandraCluster.getCassandraConsistenciesConfiguration()));
-
-            aclMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(key).rights(rights).asAddition()).block();
+            cassandraACLMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(key).rights(rights).asAddition()).block();
             return true;
         });
     }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
index 434c367..f6f8cef 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperV2Test.java
@@ -30,7 +30,14 @@ import java.util.concurrent.TimeoutException;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.Scenario.Barrier;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
+import org.apache.james.backends.cassandra.init.configuration.CassandraConsistenciesConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
+import org.apache.james.backends.cassandra.versions.SchemaVersion;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.junit.jupiter.api.BeforeEach;
@@ -39,16 +46,23 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraACLMapperV2Test extends CassandraACLMapperContract {
     @RegisterExtension
-    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraAclModule.MODULE);
+    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(
+        CassandraModule.aggregateModules(CassandraAclModule.MODULE, CassandraSchemaVersionModule.MODULE));
 
     private CassandraACLMapper cassandraACLMapper;
 
     @BeforeEach
     void setUp(CassandraCluster cassandra) {
         cassandra.getConf().printStatements();
-        cassandraACLMapper = new CassandraACLMapper(
+        CassandraSchemaVersionDAO schemaVersionDAO = new CassandraSchemaVersionDAO(cassandra.getConf());
+        schemaVersionDAO.truncateVersion().block();
+        schemaVersionDAO.updateVersion(new SchemaVersion(10)).block();
+        CassandraSchemaVersionManager versionManager = new CassandraSchemaVersionManager(schemaVersionDAO);
+        cassandraACLMapper =  new CassandraACLMapper(
             new CassandraUserMailboxRightsDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
-            new CassandraACLDAOV2(cassandra.getConf()));
+            new CassandraACLDAOV1(cassandra.getConf(), CassandraConfiguration.DEFAULT_CONFIGURATION, CassandraConsistenciesConfiguration.DEFAULT),
+            new CassandraACLDAOV2(cassandra.getConf()),
+            versionManager);
     }
 
     @Override
@@ -68,8 +82,8 @@ class CassandraACLMapperV2Test extends CassandraACLMapperContract {
         MailboxACL.EntryKey keyBob = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false);
         MailboxACL.Rfc4314Rights rights = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read);
         MailboxACL.EntryKey keyAlice = new MailboxACL.EntryKey("alice", MailboxACL.NameType.user, false);
-        Future<Boolean> future1 = performACLUpdateInExecutor(cassandra, executor, keyBob, rights);
-        Future<Boolean> future2 = performACLUpdateInExecutor(cassandra, executor, keyAlice, rights);
+        Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights);
+        Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights);
 
         barrier.awaitCaller();
         barrier.releaseCaller();
@@ -95,8 +109,8 @@ class CassandraACLMapperV2Test extends CassandraACLMapperContract {
 
         MailboxACL.EntryKey keyBob = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false);
         MailboxACL.EntryKey keyAlice = new MailboxACL.EntryKey("alice", MailboxACL.NameType.user, false);
-        Future<Boolean> future1 = performACLUpdateInExecutor(cassandra, executor, keyBob, rights);
-        Future<Boolean> future2 = performACLUpdateInExecutor(cassandra, executor, keyAlice, rights);
+        Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights);
+        Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights);
 
         barrier.awaitCaller();
         barrier.releaseCaller();
@@ -114,13 +128,9 @@ class CassandraACLMapperV2Test extends CassandraACLMapperContract {
         }
     }
 
-    private Future<Boolean> performACLUpdateInExecutor(CassandraCluster cassandra, ExecutorService executor, MailboxACL.EntryKey key, MailboxACL.Rfc4314Rights rights) {
+    private Future<Boolean> performACLUpdateInExecutor(ExecutorService executor, MailboxACL.EntryKey key, MailboxACL.Rfc4314Rights rights) {
         return executor.submit(() -> {
-            CassandraACLMapper aclMapper = new CassandraACLMapper(
-                new CassandraUserMailboxRightsDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
-                new CassandraACLDAOV2(cassandra.getConf()));
-
-            aclMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(key).rights(rights).asAddition()).block();
+            cassandraACLMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(key).rights(rights).asAddition()).block();
             return true;
         });
     }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
index f5c2f6b..678dd69 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
@@ -105,7 +105,9 @@ class CassandraMailboxMapperTest {
             new CassandraUserMailboxRightsDAO(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             new CassandraACLDAOV1(cassandra.getConf(),
                 CassandraConfiguration.DEFAULT_CONFIGURATION,
-                cassandraCluster.getCassandraConsistenciesConfiguration()));
+                cassandraCluster.getCassandraConsistenciesConfiguration()),
+            new CassandraACLDAOV2(cassandra.getConf()),
+            new CassandraSchemaVersionManager(new CassandraSchemaVersionDAO(cassandra.getConf())));
         versionDAO = new CassandraSchemaVersionDAO(cassandra.getConf());
 
         versionDAO.truncateVersion()
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskSerializationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskSerializationTest.java
new file mode 100644
index 0000000..711bb3e
--- /dev/null
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTaskSerializationTest.java
@@ -0,0 +1,52 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail.migration;
+
+import static org.mockito.Mockito.mock;
+
+import java.time.Instant;
+
+import org.apache.james.JsonSerializationVerifier;
+import org.junit.jupiter.api.Test;
+
+class AclV2MigrationTaskSerializationTest {
+    private static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
+    private static final AclV2Migration MIGRATION = mock(AclV2Migration.class);
+    private static final AclV2Migration.AclV2MigrationTask TASK = new AclV2Migration.AclV2MigrationTask(MIGRATION);
+    private static final String SERIALIZED_TASK = "{\"type\": \"acl-v2-migration\"}";
+    private static final AclV2Migration.AdditionalInformation DETAILS = new AclV2Migration.AdditionalInformation(TIMESTAMP);
+    private static final String SERIALIZED_ADDITIONAL_INFORMATION = "{\"type\": \"acl-v2-migration\", \"timestamp\":\"2018-11-13T12:00:55Z\"}";
+
+    @Test
+    void taskShouldBeSerializable() throws Exception {
+        JsonSerializationVerifier.dtoModule(AclV2MigrationTaskDTO.MODULE.apply(MIGRATION))
+            .bean(TASK)
+            .json(SERIALIZED_TASK)
+            .verify();
+    }
+
+    @Test
+    void additionalInformationShouldBeSerializable() throws Exception {
+        JsonSerializationVerifier.dtoModule(AclV2MigrationTaskAdditionalInformationDTO.MODULE)
+            .bean(DETAILS)
+            .json(SERIALIZED_ADDITIONAL_INFORMATION)
+            .verify();
+    }
+}
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTest.java
new file mode 100644
index 0000000..213df82
--- /dev/null
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AclV2MigrationTest.java
@@ -0,0 +1,112 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail.migration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
+import org.apache.james.backends.cassandra.init.configuration.CassandraConsistenciesConfiguration;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
+import org.apache.james.core.Username;
+import org.apache.james.mailbox.cassandra.ids.CassandraId;
+import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV1;
+import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV2;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
+import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
+import org.apache.james.mailbox.model.Mailbox;
+import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.UidValidity;
+import org.apache.james.task.Task;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import com.google.common.collect.ImmutableMap;
+
+class AclV2MigrationTest {
+    private static final CassandraId MAILBOX_ID = CassandraId.timeBased();
+    private static final Mailbox MAILBOX = new Mailbox(new MailboxPath(MailboxConstants.USER_NAMESPACE, Username.of("bob"), MailboxConstants.INBOX),
+        UidValidity.generate(), MAILBOX_ID);
+
+    public static final CassandraModule MODULES = CassandraModule.aggregateModules(
+        CassandraMailboxModule.MODULE,
+        CassandraAclModule.MODULE,
+        CassandraSchemaVersionModule.MODULE);
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(MODULES);
+
+    private CassandraACLDAOV1 daoV1;
+    private CassandraACLDAOV2 daoV2;
+    private CassandraMailboxDAO mailboxDAO;
+    private AclV2Migration migration;
+
+    @BeforeEach
+    void setUp(CassandraCluster cassandra) {
+        mailboxDAO = new CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider(), CassandraConsistenciesConfiguration.DEFAULT);
+        daoV1 = new CassandraACLDAOV1(cassandra.getConf(), CassandraConfiguration.DEFAULT_CONFIGURATION, CassandraConsistenciesConfiguration.DEFAULT);
+        daoV2 = new CassandraACLDAOV2(cassandra.getConf());
+        migration = new AclV2Migration(mailboxDAO, daoV1, daoV2);
+    }
+
+    @Test
+    void shouldCompleteWhenNoMailboxes() throws Exception {
+        Task.Result result = migration.runTask();
+
+        assertThat(result).isEqualTo(Task.Result.COMPLETED);
+    }
+
+    @Test
+    void shouldCompleteWhenMailboxWithNoAcl() throws Exception {
+        mailboxDAO.save(MAILBOX).block();
+
+        Task.Result result = migration.runTask();
+
+        assertThat(result).isEqualTo(Task.Result.COMPLETED);
+    }
+
+    @Test
+    void shouldCompleteWhenMailboxWithAcl() throws Exception {
+        mailboxDAO.save(MAILBOX).block();
+        MailboxACL acl = new MailboxACL(ImmutableMap.of(MailboxACL.EntryKey.createUserEntryKey(Username.of("alice")), MailboxACL.FULL_RIGHTS));
+        daoV1.setACL(MAILBOX_ID, acl).block();
+
+        Task.Result result = migration.runTask();
+
+        assertThat(result).isEqualTo(Task.Result.COMPLETED);
+    }
+
+    @Test
+    void shouldCopyAclToNewestVersion() throws Exception {
+        mailboxDAO.save(MAILBOX).block();
+        MailboxACL acl = new MailboxACL(ImmutableMap.of(MailboxACL.EntryKey.createUserEntryKey(Username.of("alice")), MailboxACL.FULL_RIGHTS));
+        daoV1.setACL(MAILBOX_ID, acl).block();
+
+        Task.Result result = migration.runTask();
+
+        assertThat(daoV2.getACL(MAILBOX_ID).block()).isEqualTo(acl);
+    }
+}
\ No newline at end of file
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTest.java
index 7ab3f53..0d72d2b 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/MailboxPathV2MigrationTest.java
@@ -32,6 +32,7 @@ import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV1;
+import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraACLMapper;
 import org.apache.james.mailbox.cassandra.mail.CassandraIdAndPath;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
@@ -104,7 +105,9 @@ class MailboxPathV2MigrationTest {
                 new CassandraACLDAOV1(
                     cassandra.getConf(),
                     CassandraConfiguration.DEFAULT_CONFIGURATION,
-                    cassandraCluster.getCassandraConsistenciesConfiguration())),
+                    cassandraCluster.getCassandraConsistenciesConfiguration()),
+                new CassandraACLDAOV2(cassandra.getConf()),
+                new CassandraSchemaVersionManager(new CassandraSchemaVersionDAO(cassandra.getConf()))),
             new CassandraSchemaVersionManager(new CassandraSchemaVersionDAO(cassandra.getConf())),
             CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
index 0afa4fb..5db0098 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
@@ -42,6 +42,7 @@ import org.apache.james.mailbox.cassandra.DeleteMessageListener;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV1;
+import org.apache.james.mailbox.cassandra.mail.CassandraACLDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraACLMapper;
 import org.apache.james.mailbox.cassandra.mail.CassandraApplicableFlagDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
@@ -123,6 +124,7 @@ public class CassandraMailboxModule extends AbstractModule {
         bind(CassandraMailboxCounterDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxDAO.class).in(Scopes.SINGLETON);
         bind(CassandraACLDAOV1.class).in(Scopes.SINGLETON);
+        bind(CassandraACLDAOV2.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxPathDAOImpl.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxPathV2DAO.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxPathV3DAO.class).in(Scopes.SINGLETON);
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/webadmin/CassandraRoutesModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/webadmin/CassandraRoutesModule.java
index ff0f783..31caeed 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/webadmin/CassandraRoutesModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/webadmin/CassandraRoutesModule.java
@@ -25,6 +25,7 @@ import org.apache.james.backends.cassandra.migration.MigrationTask;
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
 import org.apache.james.backends.cassandra.versions.SchemaTransition;
 import org.apache.james.backends.cassandra.versions.SchemaVersion;
+import org.apache.james.mailbox.cassandra.mail.migration.AclV2Migration;
 import org.apache.james.mailbox.cassandra.mail.migration.MailboxPathV2Migration;
 import org.apache.james.mailbox.cassandra.mail.migration.MailboxPathV3Migration;
 import org.apache.james.mailbox.cassandra.mail.migration.MessageV3Migration;
@@ -44,6 +45,7 @@ public class CassandraRoutesModule extends AbstractModule {
     private static final SchemaTransition FROM_V6_TO_V7 = SchemaTransition.to(new SchemaVersion(7));
     private static final SchemaTransition FROM_V7_TO_V8 = SchemaTransition.to(new SchemaVersion(8));
     private static final SchemaTransition FROM_V8_TO_V9 = SchemaTransition.to(new SchemaVersion(9));
+    private static final SchemaTransition FROM_V9_TO_V10 = SchemaTransition.to(new SchemaVersion(10));
 
     @Override
     protected void configure() {
@@ -63,6 +65,7 @@ public class CassandraRoutesModule extends AbstractModule {
         allMigrationClazzBinder.addBinding(FROM_V6_TO_V7).to(MappingsSourcesMigration.class);
         allMigrationClazzBinder.addBinding(FROM_V7_TO_V8).to(MailboxPathV3Migration.class);
         allMigrationClazzBinder.addBinding(FROM_V8_TO_V9).to(MessageV3Migration.class);
+        allMigrationClazzBinder.addBinding(FROM_V9_TO_V10).to(AclV2Migration.class);
 
         bind(SchemaVersion.class)
             .annotatedWith(Names.named(CassandraMigrationService.LATEST_VERSION))


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org