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 ece9245833c183668371a06ae8ac5934efd03deb
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Thu Aug 24 17:12:03 2023 +0700

    JAMES-3926 Implement SieveQuotaMigration
---
 .../cassandra/migration/SieveQuotaMigration.java   |  67 ++++++++++
 .../migration/SieveQuotaMigrationTest.java         | 141 +++++++++++++++++++++
 2 files changed, 208 insertions(+)

diff --git 
a/server/data/data-cassandra/src/main/java/org/apache/james/sieve/cassandra/migration/SieveQuotaMigration.java
 
b/server/data/data-cassandra/src/main/java/org/apache/james/sieve/cassandra/migration/SieveQuotaMigration.java
new file mode 100644
index 0000000000..287bd01c52
--- /dev/null
+++ 
b/server/data/data-cassandra/src/main/java/org/apache/james/sieve/cassandra/migration/SieveQuotaMigration.java
@@ -0,0 +1,67 @@
+/****************************************************************
+ * 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.sieve.cassandra.migration;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.james.backends.cassandra.migration.Migration;
+import org.apache.james.core.Username;
+import org.apache.james.sieve.cassandra.CassandraSieveQuotaDAO;
+import org.apache.james.user.api.UsersRepository;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class SieveQuotaMigration implements Migration {
+    private final UsersRepository usersRepository;
+    private final CassandraSieveQuotaDAO oldDAO;
+    private final CassandraSieveQuotaDAO newDAO;
+
+    @Inject
+    public SieveQuotaMigration(UsersRepository usersRepository, @Named("old") 
CassandraSieveQuotaDAO oldDAO, CassandraSieveQuotaDAO newDAO) {
+        this.usersRepository = usersRepository;
+        this.oldDAO = oldDAO;
+        this.newDAO = newDAO;
+    }
+
+    @Override
+    public void apply() throws InterruptedException {
+        oldDAO.getQuota()
+            .flatMap(maybeLimit -> 
maybeLimit.map(newDAO::setQuota).orElse(Mono.empty()))
+            .block();
+
+        Flux.from(usersRepository.listReactive())
+            .flatMap(username -> migrateLimit(username)
+                .then(migrateCurrentValue(username)))
+            .then()
+            .block();
+    }
+
+    private Mono<Void> migrateCurrentValue(Username username) {
+        return oldDAO.spaceUsedBy(username)
+            .flatMap(currentValue -> newDAO.updateSpaceUsed(username, 
currentValue));
+    }
+
+    private Mono<Void> migrateLimit(Username username) {
+        return oldDAO.getQuota(username)
+            .flatMap(maybeLimit -> maybeLimit.map(limit -> 
newDAO.setQuota(username, limit)).orElse(Mono.empty()));
+    }
+}
diff --git 
a/server/data/data-cassandra/src/test/java/org/apache/james/sieve/cassandra/migration/SieveQuotaMigrationTest.java
 
b/server/data/data-cassandra/src/test/java/org/apache/james/sieve/cassandra/migration/SieveQuotaMigrationTest.java
new file mode 100644
index 0000000000..f7006148c5
--- /dev/null
+++ 
b/server/data/data-cassandra/src/test/java/org/apache/james/sieve/cassandra/migration/SieveQuotaMigrationTest.java
@@ -0,0 +1,141 @@
+/****************************************************************
+ * 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.sieve.cassandra.migration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import 
org.apache.james.backends.cassandra.components.CassandraMutualizedQuotaModule;
+import 
org.apache.james.backends.cassandra.components.CassandraQuotaCurrentValueDao;
+import org.apache.james.backends.cassandra.components.CassandraQuotaLimitDao;
+import org.apache.james.core.Domain;
+import org.apache.james.core.Username;
+import org.apache.james.core.quota.QuotaSizeLimit;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.api.mock.SimpleDomainList;
+import org.apache.james.domainlist.cassandra.CassandraDomainListModule;
+import org.apache.james.sieve.cassandra.CassandraSieveQuotaDAO;
+import org.apache.james.sieve.cassandra.CassandraSieveQuotaDAOV1;
+import org.apache.james.sieve.cassandra.CassandraSieveQuotaDAOV2;
+import org.apache.james.sieve.cassandra.CassandraSieveRepositoryModule;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.cassandra.CassandraUsersDAO;
+import org.apache.james.user.cassandra.CassandraUsersRepositoryModule;
+import org.apache.james.user.lib.UsersRepositoryImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+class SieveQuotaMigrationTest {
+    public static final Username BOB = Username.of("bob");
+
+    private UsersRepositoryImpl<CassandraUsersDAO> getUsersRepository() throws 
Exception {
+        boolean enableVirtualHosting = false;
+        DomainList domainList = new SimpleDomainList();
+        domainList.addDomain(Domain.of("domain.tld"));
+        CassandraUsersDAO usersDAO = new 
CassandraUsersDAO(cassandraCluster.getCassandraCluster().getConf());
+        BaseHierarchicalConfiguration configuration = new 
BaseHierarchicalConfiguration();
+        configuration.addProperty("enableVirtualHosting", 
String.valueOf(enableVirtualHosting));
+
+        UsersRepositoryImpl<CassandraUsersDAO> usersRepository = new 
UsersRepositoryImpl<>(domainList, usersDAO);
+        usersRepository.configure(configuration);
+        return usersRepository;
+    }
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(CassandraModule.aggregateModules(
+        CassandraSieveRepositoryModule.MODULE,
+        CassandraUsersRepositoryModule.MODULE,
+        CassandraDomainListModule.MODULE,
+        CassandraMutualizedQuotaModule.MODULE));
+
+    private CassandraSieveQuotaDAOV1 oldDAO;
+    private CassandraSieveQuotaDAOV2 newDAO;
+    private SieveQuotaMigration testee;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        oldDAO = new 
CassandraSieveQuotaDAOV1(cassandraCluster.getCassandraCluster().getConf());
+        newDAO = new CassandraSieveQuotaDAOV2(new 
CassandraQuotaCurrentValueDao(cassandraCluster.getCassandraCluster().getConf()),
+            new 
CassandraQuotaLimitDao(cassandraCluster.getCassandraCluster().getConf()));
+        UsersRepository usersRepository = getUsersRepository();
+
+        usersRepository.addUser(BOB, "passBob");
+
+        testee = new SieveQuotaMigration(usersRepository, oldDAO, newDAO);
+    }
+
+    @Test
+    void shouldMigrateGlobalLimit() throws Exception {
+        oldDAO.setQuota(QuotaSizeLimit.size(32)).block();
+
+        testee.apply();
+
+        assertThat(newDAO.getQuota().block())
+            .contains(QuotaSizeLimit.size(32));
+    }
+
+    @Test
+    void shouldNotFailWhenNoGlobalLimit() throws Exception {
+        testee.apply();
+
+        assertThat(newDAO.getQuota().block())
+            .isEmpty();
+    }
+
+    @Test
+    void shouldNotFailWhenNoUserLimit() throws Exception {
+        testee.apply();
+
+        assertThat(newDAO.getQuota(BOB).block())
+            .isEmpty();
+    }
+
+    @Test
+    void shouldNotFailWhenNoSpaceUsed() throws Exception {
+        testee.apply();
+
+        assertThat(newDAO.spaceUsedBy(BOB).block())
+            .isEqualTo(0L);
+    }
+
+    @Test
+    void shouldMigrateUserSpace() throws Exception {
+        oldDAO.updateSpaceUsed(BOB, 42).block();
+
+        testee.apply();
+
+        assertThat(newDAO.spaceUsedBy(BOB).block())
+            .isEqualTo(42L);
+    }
+
+
+    @Test
+    void shouldMigrateUserLimit() throws Exception {
+        oldDAO.setQuota(BOB, QuotaSizeLimit.size(90)).block();
+
+        testee.apply();
+
+        assertThat(newDAO.getQuota(BOB).block())
+            .contains(QuotaSizeLimit.size(90));
+    }
+}
\ No newline at end of file


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

Reply via email to